PHP設計模式之責任鏈模式

责任链模式,其目的是组织一个对象链处理一个如方法调用的请求。

当ConcreteHandler(具体的处理程序)不知道如何满足来自Client的请求时,或它的目的不是这个时,它会委派给链中的下一个Handler(处理程序)来处理。
这个设计模式通常和复合模式一起使用,其中有些叶子或容器对象默认委派操作给它们的父对象。另一个例子是,本地化通常是使用责任链处理的,当德语翻译适配器没有为翻译关键词找到合适的结果时,就返回到英语适配器或干脆直接显示关键词本身。

耦合减少到最低限度:Client类不知道由哪个具体的类来处理请求;在创建对象图时配置了链;ConcreteHandlers不知道哪个对象是它们的继承者。行为在对象之间分配是成功的,链中最近的对象有优先权和责任满足请求。

PHP设计模式中的责任链模式 
PHP设计模式中的责任链模式

参与者:

◆Client(客户端):向Handler(处理程序)提交一个请求;

◆Handler(处理程序)抽象:接收一个请求,以某种方式满足它;

◆ConcreteHandlers(具体的处理程序):接收一个请求,设法满足它,如果不成功就委派给下一个处理程序。

下面的代码实现了一个最著名的责任链示例:多级缓存。

 
 
  1. <?php  
  2. /**  
  3.  * The Handler abstraction. Objects that want to be a part of the  
  4.  * ChainOfResponsibility must implement this interface directly or via  
  5.  * inheritance from an AbstractHandler.  
  6.  */ 
  7. interface KeyValueStore  
  8. {  
  9.     /**  
  10.      * Obtain a value.  
  11.      * @param string $key  
  12.      * @return mixed  
  13.      */ 
  14.     public function get($key);  
  15. }  
  16.  
  17. /**  
  18.  * Basic no-op implementation which ConcreteHandlers not interested in  
  19.  * caching or in interfering with the retrieval inherit from.  
  20.  */ 
  21. abstract class AbstractKeyValueStore implements KeyValueStore  
  22. {  
  23.     protected $_nextHandler;  
  24.  
  25.     public function get($key)  
  26.     {  
  27.         return $this->_nextHandler->get($key);  
  28.     }  
  29. }  
  30.  
  31. /**  
  32.  * Ideally the last ConcreteHandler in the chain. At least, if inserted in  
  33.  * a Chain it will be the last node to be called.  
  34.  */ 
  35. class SlowStore implements KeyValueStore  
  36. {  
  37.     /**  
  38.      * This could be a somewhat slow store: a database or a flat file.  
  39.      */ 
  40.     protected $_values;  
  41.  
  42.     public function __construct(array $values = array())  
  43.     {  
  44.         $this->_values = $values;  
  45.     }  
  46.  
  47.     public function get($key)  
  48.     {  
  49.         return $this->_values[$key];  
  50.     }  
  51. }  
  52.  
  53. /**  
  54.  * A ConcreteHandler that handles the request for a key by looking for it in  
  55.  * its own cache. Forwards to the next handler in case of cache miss.  
  56.  */ 
  57. class InMemoryKeyValueStore implements KeyValueStore  
  58. {  
  59.     protected $_nextHandler;  
  60.     protected $_cached = array();  
  61.  
  62.     public function __construct(KeyValueStore $nextHandler)  
  63.     {  
  64.         $this->_nextHandler = $nextHandler;  
  65.     }  
  66.  
  67.     protected function _load($key)  
  68.     {  
  69.         if (!isset($this->_cached[$key])) {  
  70.             $this->_cached[$key] = $this->_nextHandler->get($key);  
  71.         }  
  72.     }  
  73.  
  74.     public function get($key)  
  75.     {  
  76.         $this->_load($key);  
  77.         return $this->_cached[$key];  
  78.     }  
  79. }  
  80.  
  81. /**  
  82.  * A ConcreteHandler that delegates the request without trying to  
  83.  * understand it at all. It may be easier to use in the user interface  
  84.  * because it can specialize itself by defining methods that generates  
  85.  * html, or by addressing similar user interface concerns.  
  86.  * Some Clients see this object only as an instance of KeyValueStore  
  87.  * and do not care how it satisfy their requests, while other ones  
  88.  * may use it in its entirety (similar to a class-based adapter).  
  89.  * No client knows that a chain of Handlers exists.  
  90.  */ 
  91. class FrontEnd extends AbstractKeyValueStore  
  92. {  
  93.     public function __construct(KeyValueStore $nextHandler)  
  94.     {  
  95.         $this->_nextHandler = $nextHandler;  
  96.     }  
  97.  
  98.     public function getEscaped($key)  
  99.     {  
  100.         return htmlentities($this->get($key), ENT_NOQUOTES, 'UTF-8');  
  101.     }  
  102. }  
  103.  
  104. // Client code  
  105. $store = new SlowStore(array('pd' => 'Philip K. Dick',  
  106.                              'ia' => 'Isaac Asimov',  
  107.                              'ac' => 'Arthur C. Clarke',  
  108.                              'hh' => 'Helmut Heißenbüttel'));  
  109. // in development, we skip cache and pass $store directly to FrontEnd  
  110. $cache = new InMemoryKeyValueStore($store);  
  111. $frontEnd = new FrontEnd($cache);  
  112.  
  113. echo $frontEnd->get('ia'), "\n";  
  114. echo $frontEnd->getEscaped('hh'), "\n"
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值