1、模式定义 责任链模式将处理请求的对象连成一条链,沿着这条链传递该请求,直到有一个对象处理请求为止,这使得多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。
责任链模式在现实中使用的很多,常见的就是 oa 系统中的工作流。
2、uml 类图
3、示例代码 request.php successor = $handler; } else { $this->successor->append($handler); } } /** * 处理请求 * * this approach by using a template method pattern ensures you that * each subclass will not forget to call the successor. besides, the returned * boolean value indicates you if the request have been processed or not. * * @param request $req * * @return bool */ final public function handle(request $req) { $req->fordebugonly = get_called_class(); $processed = $this->processing($req); if (!$processed) { // the request has not been processed by this handler => see the next if (!is_null($this->successor)) { $processed = $this->successor->handle($req); } } return $processed; } /** * 每个处理器具体实现类都要实现这个方法对请求进行处理 * * @param request $req * * @return bool true if the request has been processed */ abstract protected function processing(request $req);}
responsible/slowstorage.php data = $data; } protected function processing(request $req) { if ('get' === $req->verb) { if (array_key_exists($req->key, $this->data)) { $req->response = $this->data[$req->key]; return true; } } return false; }}
responsible/faststorage.php data = $data; } protected function processing(request $req) { if ('get' === $req->verb) { if (array_key_exists($req->key, $this->data)) { // the handler is responsible and then processes the request $req->response = $this->data[$req->key]; // instead of returning true, i could return the value but it proves // to be a bad idea. what if the value is false ? return true; } } return false; }}
4、测试代码 tests/chaintest.php chain = new faststorage(array('bar' => 'baz')); $this->chain->append(new slowstorage(array('bar' => 'baz', 'foo' => 'bar'))); } public function makerequest() { $request = new request(); $request->verb = 'get'; return array( array($request) ); } /** * @dataprovider makerequest */ public function testfaststorage($request) { $request->key = 'bar'; $ret = $this->chain->handle($request); $this->asserttrue($ret); $this->assertobjecthasattribute('response', $request); $this->assertequals('baz', $request->response); // despite both handle owns the 'bar' key, the faststorage is responding first $classname = 'designpatterns\behavioral\chainofresponsibilities\responsible\faststorage'; $this->assertequals($classname, $request->fordebugonly); } /** * @dataprovider makerequest */ public function testslowstorage($request) { $request->key = 'foo'; $ret = $this->chain->handle($request); $this->asserttrue($ret); $this->assertobjecthasattribute('response', $request); $this->assertequals('bar', $request->response); // faststorage has no 'foo' key, the slowstorage is responding $classname = 'designpatterns\behavioral\chainofresponsibilities\responsible\slowstorage'; $this->assertequals($classname, $request->fordebugonly); } /** * @dataprovider makerequest */ public function testfailure($request) { $request->key = 'kurukuku'; $ret = $this->chain->handle($request); $this->assertfalse($ret); // the last responsible : $classname = 'designpatterns\behavioral\chainofresponsibilities\responsible\slowstorage'; $this->assertequals($classname, $request->fordebugonly); }}
5、总结 责任链模式的主要优点在于可以降低系统的耦合度,简化对象的相互连接,同时增强给对象指派职责的灵活性,增加新的请求处理类也很方便;其主要缺点在于不能保证请求一定被接收,且对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便。