// C++ // text-encoding : shift_jis #include using namespace std; // チェインのための Handler クラス class Handler { private: // 次の handler Handler* successor_; // 'リクエスト' class Request { friend class Handler; virtual void sendTo( Handler* p ) const = 0; virtual bool sendableTo( const Handler* p ) const = 0; }; public: template class RequestGen : public Request { void sendTo( Handler* p ) const { dynamic_cast(p)->invoke(); } bool sendableTo( const Handler* p ) const { return dynamic_cast(p)!=0; } }; // コンストラクタ Handler( Handler* successor ) : successor_(successor) {} // デストラクタ virtual ~Handler() {} // リクエストが受付可能かどうかのチェック bool hasHandler( const Request& req ) const { return req.sendableTo(this); } // リクエストを処理する void handleRequest( const Request& req ) { if( req.sendableTo(this) ) { req.sendTo(this); } else if( successor_ ) { successor_->handleRequest(req); } } }; // リクエスト 'HELP' struct HelpHandler { void invoke() { help(); } virtual void help() = 0; }; static Handler::RequestGen HELP_REQUEST; // リクエスト 'PRINT' struct PrintHandler { void invoke() { print(); } virtual void print() = 0; }; static Handler::RequestGen PRINT_REQUEST; // リクエスト 'PREVIEW' struct PreviewHandler { void invoke() { preview(); } virtual void preview() = 0; }; static Handler::RequestGen PREVIEW_REQUEST; // Button クラス class Button : public Handler, public HelpHandler { public: Button( Handler* suc ) : Handler(suc) {} void help() { cout << "ButtonHelp" << endl; } }; // Application クラス class Application : public Handler, public PreviewHandler { public: Application( Handler* suc ) : Handler(suc) {} void preview() { cout << "AppPreview" << endl; } }; // Dialog クラス class Dialog : public Handler, public PrintHandler { public: Dialog( Handler* suc ) : Handler(suc) {} void print() { cout << "DialogPrint" << endl; } }; int main() { Application app(0); Dialog dialog(&app); Button button(&dialog); button.handleRequest(HELP_REQUEST); button.handleRequest(PRINT_REQUEST); button.handleRequest(PREVIEW_REQUEST); }