大话设计模式--职责连模式 Chain of Resposibility -- C++实现实例
1. 职责链模式: 使多个对象都有机会处理请求,从而避免请求发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。
当客户提交一个请求时,请求是沿着链传递直到有一个ConcreteHandler对象负责处理它,接收者和发送者都没有对方的明确信息,且链中的对象并不知道链的结构。
结果是职责链可以简化对象的互相连接,他们仅需一个指向其后继者的引用,而不需要保持它所有后继者的引用。
一个请求极有可能到了链的最末端还是得不到处理,或者没有正确配置而得不到处理,需要事先考虑全面。
实例:
handler.h handler.cpp
#ifndef HANDLER_H #define HANDLER_H class Handler { public: Handler(); ~Handler(); void setSuccessor(Handler *successor); void virtual handlerRequest(int request)=0; protected: Handler *successor; }; #endif // HANDLER_H
#include "handler.h" Handler::Handler() { successor = 0; } Handler::~Handler() { delete successor; } void Handler::setSuccessor(Handler *successor) { this->successor = successor; }
concretehandler1.h concretehandler1.cpp
#ifndef CONCRETEHANDLER1_H #define CONCRETEHANDLER1_H #include "handler.h" class ConcreteHandler1 : public Handler { public: ConcreteHandler1(); void handlerRequest(int request); }; #endif // CONCRETEHANDLER1_H
#include "concretehandler1.h" #include <stdio.h> ConcreteHandler1::ConcreteHandler1() { } void ConcreteHandler1::handlerRequest(int request) { if( request >=0 && request < 10 ) { printf("ConcreteHandler1 handlerRequest\n"); } else { if( successor!=0 ) { printf("the next one handler\n"); successor->handlerRequest(request); } } }
concretehandler2.h concretehandler2.cpp
#ifndef CONCRETEHANDLER2_H #define CONCRETEHANDLER2_H #include "handler.h" class ConcreteHandler2 : public Handler { public: ConcreteHandler2(); void handlerRequest(int request); }; #endif // CONCRETEHANDLER2_H
#include "concretehandler2.h" #include <stdio.h> ConcreteHandler2::ConcreteHandler2() { } void ConcreteHandler2::handlerRequest(int request) { if( request >=10 && request < 20 ) { printf("ConcreteHandler2 handlerRequest\n"); } else { if( successor!=0 ) { printf("the next one handler\n"); successor->handlerRequest(request); } } }
main.cpp
#include <iostream> #include "concretehandler1.h" #include "concretehandler2.h" using namespace std; int main() { cout << "Chain_of_responsibility test!" << endl; Handler *h1 = new ConcreteHandler1(); Handler *h2 = new ConcreteHandler2(); h1->setSuccessor(h2); h1->handlerRequest(15); return 0; }