您的位置:首页 > 大数据 > 人工智能

笔记:Gof设计模式--Chain of Responsibility

2012-06-02 18:01 357 查看
1、意图
Avoid coupling the sender of a request to its receiver by giving morethan one object a chance to handle the request. Chain the receivingobjects and pass the request along the chain until an objecthandles
it.

2、适应性

Use Chain of Responsibility when

• more than one object may handle a request, and the handler isn't knowna priori. The handler should be ascertained automatically.

• you want to issue a request to one of several objects withoutspecifying the receiver explicitly.

• the set of objects that can handle a request should be specifieddynamically.

3、结构



[align=left] [/align]

4、示例代码

The HelpHandler class defines the interface for handlinghelp requests. It maintains a help topic (which is empty by default)and keeps a reference to its successor on the chain of help handlers.The key operation is HandleHelp,
which subclassesoverride. HasHelp is a convenience operation for checkingwhether there is an associated help topic.

typedef int Topic;
const Topic NO_HELP_TOPIC = -1;

class HelpHandler {
public:
HelpHandler(HelpHandler* = 0, Topic = NO_HELP_
virtual bool HasHelp();
virtual void SetHandler(HelpHandler*, Topic);
virtual void HandleHelp();
private:
HelpHandler* _successor;
Topic _topic;
};

HelpHandler::HelpHandler (
HelpHandler* h, Topic t
) : _successor(h), _topic(t) { }

bool HelpHandler::HasHelp () {
return _topic != NO_HELP_TOPIC;
}

void HelpHandler::HandleHelp () {
if (_successor != 0) {
successor->HandleHelp();
}
}


All widgets are subclasses of the Widget abstract class.Widget is a subclass of HelpHandler, since alluser interface elements can have help associated with them. (We couldhave used a mixin-based implementation just as well.)

class Widget : public HelpHandler {
protected:
Widget(Widget* parent, Topic t = NO_HELP_TOPIC);
private:
Widget* _parent;
};

Widget::Widget (Widget* w, Topic t) : HelpHandler(w, t) {
_parent = w;
}


In our example, a button is the first handler on the chain. TheButton class is a subclass of Widget.

class Button : public Widget {
public:
Button(Widget* d, Topic t = NO_HELP_TOPIC);
virtual void HandleHelp();
// Widget operations that Button overrides...
};

Button::Button (Widget* h, Topic t) : Widget(h, t) { }

void Button::HandleHelp () {
if (HasHelp()) {
// offer help on the button
} else {
HelpHandler::HandleHelp();
}
}


class Dialog : public Widget {
public:
Dialog(HelpHandler* h, Topic t = NO_HELP_TOPIC);
virtual void HandleHelp();
// Widget operations that Dialog overrides...
// ...
};

Dialog::Dialog (HelpHandler* h,  Topic t) : Widget(0) {
SetHandler(h, t);
}

void Dialog::HandleHelp () {
if (HasHelp()) {
// offer help on the dialog
} else {
HelpHandler::HandleHelp();
}
}


class Application : public HelpHandler {
public:
Application(Topic t) : HelpHandler(0, t) { }
virtual void HandleHelp();
// application-specific operations...
};

void Application::HandleHelp () {
// show a list of help topics
}


const Topic PRINT_TOPIC = 1;
const Topic PAPER_ORIENTATION_TOPIC = 2;
const Topic APPLICATION_TOPIC = 3;

Application* application = new Application(APPLICATION_TOPIC);
Dialog* dialog = new Dialog(application, PRINT_TOPIC);
Button* button = new Button(dialog, PAPER_ORIENTATION_TOPIC);
We can invoke the help request by calling HandleHelp on anyobject on the chain
To start the search at the button object, justcall HandleHelp on it:
button->HandleHelp();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: