diff --git a/14_chain_of_responsibility.cpp b/14_chain_of_responsibility.cpp new file mode 100644 index 0000000..1fa113a --- /dev/null +++ b/14_chain_of_responsibility.cpp @@ -0,0 +1,80 @@ +#include +#include + + +using namespace std; + +class Request { +public: + int days; + enum { + PERSONAL_LEAVE, + ANNUAL_LEAVE, + } reason; +}; + + +class Handler { + shared_ptr next; +public: + void next_handle(const Request& r) { + if (!next) { + cout << "Request unhandled" << endl; + } + next->handle(r); + } + + void set_next(shared_ptr n) { + next = n; + } + + virtual void handle(const Request& r) = 0; +}; + + +class LeaderHandler : public Handler { +public: + virtual void handle(const Request& r) override { + if (r.days < 3) { + cout << "Leader: OK" << endl; + } else { + next_handle(r); + } + } +}; + + +class SupervisorHandler : public Handler { +public: + virtual void handle(const Request& r) override { + if (r.days < 7 || r.reason == Request::ANNUAL_LEAVE) { + cout << "Supervisor: OK" << endl; + } else { + next_handle(r); + } + } +}; + +class ManagerHandler : public Handler { +public: + virtual void handle(const Request& r) override { + cout << "Manager: OK" << endl; + } +}; + +int main() { + auto lh = make_shared(); + auto sh = make_shared(); + auto mh = make_shared(); + + lh->set_next(sh); + sh->set_next(mh); + + Request r1 {1, Request::PERSONAL_LEAVE}; + Request r2 {4, Request::ANNUAL_LEAVE}; + Request r3 {10, Request::PERSONAL_LEAVE}; + + lh->handle(r1); + lh->handle(r2); + lh->handle(r3); +} diff --git a/notes.md b/notes.md index e9c660e..b6b66ef 100644 --- a/notes.md +++ b/notes.md @@ -89,3 +89,11 @@ 我们在使用一个类时,有时会觉得这个类的功能较简单,实际使用需要额外添加一些访问控制,缓存管理等功能。简单的想法是直接在这个类中添加这些功能,但这会使得这个类急剧膨胀,且核心功能变得不那么明确。 代理模式解决了这个问题。通过一个代理类实现目标类相同接口,客户端使用代理时就像在直接操作目标类。代理类内部有目标类的指针,在处理缓存、权限等逻辑后再去调用目标类的相关函数,从而做到外围与核心逻辑的分离。 + +## 责任链模式(Chain of Responsibility) + +有时我们会遇到如何处理用户请求的框架。一种做法是通过条件判断,得到不同条件下请求对应的处理函数。这样的话耦合严重,各个不同的 handler 需要放在一个函数或类中,每次扩展都需要改变这个类。 + +责任链模式解决了这个问题。一个 handler 要么处理这个请求,要么交给下一个 handler 处理,增加处理逻辑时,只需要新增一个 handler,并且正确设置相应的 next 即可。这样,每个 handler 只关心自己的职责,所有 handler 处理清晰。当我们能将所有的 handler 组成一个链式或者树式的结构时,这会非常有用。 + +但也正如前面提到的,这不自然支持“一个请求需多个处理者同时处理”的场景。此时可以通过责任链进一步推广成“责任网”,观察者模式,流程引擎式结构等,增强责任链模式的处理能力。