PHP設計モデルの責任チェーンモデルの深い解析

5484 ワード

メソッド呼び出しなどのリクエストを処理するオブジェクトチェーンを組織する責任チェーンモード.
ConcreteHandler(特定のプロセッサ)がClientからの要求をどのように満たすか分からない場合、またはその目的がこれではない場合、チェーン内の次のHandler(プロセッサ)に処理を委任します.
この設計モードは、通常、複合モードとともに使用されます.リーフまたはコンテナオブジェクトの一部は、親オブジェクトにデフォルトで委任されます.もう1つの例は、ローカライズは通常、責任チェーンを使用して処理され、ドイツ語の翻訳アダプタが翻訳キーワードに適切な結果を見つけていない場合、英語のアダプタに戻ったり、キーワード自体を直接表示したりすることです.
結合を最小限に抑える:Clientクラスはどの特定のクラスが要求を処理するか分からない.オブジェクト図を作成するときにチェーンを構成します.ConcreteHandlersでは、どのオブジェクトが継承者なのか分かりません.動作はオブジェクト間での割り当てに成功し、チェーン内の最近のオブジェクトには優先権と責任が要求を満たす.
参加者:◆Client(クライアント):Handler(プロセッサ)にリクエストを送信します.
◆Handler(プロセッサ)抽象:要求を受信し、何らかの方法でそれを満たす;
◆ConcreteHandlers(具体的なプロセッサ):要求を受信し、それを満たすようにし、成功しなければ次のプロセッサに委任します.
次のコードは、マルチレベルキャッシュという最も有名な責任チェーンの例を実現します.
 
  
/** 
 * The Handler abstraction. Objects that want to be a part of the 
 * ChainOfResponsibility must implement this interface directly or via 
 * inheritance from an AbstractHandler. 
 */
interface KeyValueStore 

    /** 
     * Obtain a value. 
     * @param string $key 
     * @return mixed 
     */
    public function get($key); 


/** 
 * Basic no-op implementation which ConcreteHandlers not interested in 
 * caching or in interfering with the retrieval inherit from. 
 */
abstract class AbstractKeyValueStore implements KeyValueStore 

    protected $_nextHandler; 

    public function get($key) 
    { 
 return $this->_nextHandler->get($key); 
    } 


/** 
 * Ideally the last ConcreteHandler in the chain. At least, if inserted in 
 * a Chain it will be the last node to be called. 
 */
class SlowStore implements KeyValueStore 

    /** 
     * This could be a somewhat slow store: a database or a flat file. 
     */
    protected $_values; 

    public function __construct(array $values = array()) 
    { 
 $this->_values = $values; 
    } 

    public function get($key) 
    { 
 return $this->_values[$key]; 
    } 


/** 
 * A ConcreteHandler that handles the request for a key by looking for it in 
 * its own cache. Forwards to the next handler in case of cache miss. 
 */
class InMemoryKeyValueStore implements KeyValueStore 

    protected $_nextHandler; 
    protected $_cached = array(); 

    public function __construct(KeyValueStore $nextHandler) 
    { 
 $this->_nextHandler = $nextHandler; 
    } 

    protected function _load($key) 
    { 
 if (!isset($this->_cached[$key])) { 
     $this->_cached[$key] = $this->_nextHandler->get($key); 
 } 
    } 

    public function get($key) 
    { 
 $this->_load($key); 
 return $this->_cached[$key]; 
    } 


/** 
 * A ConcreteHandler that delegates the request without trying to 
 * understand it at all. It may be easier to use in the user interface 
 * because it can specialize itself by defining methods that generates 
 * html, or by addressing similar user interface concerns. 
 * Some Clients see this object only as an instance of KeyValueStore 
 * and do not care how it satisfy their requests, while other ones 
 * may use it in its entirety (similar to a class-based adapter). 
 * No client knows that a chain of Handlers exists. 
 */
class FrontEnd extends AbstractKeyValueStore 

    public function __construct(KeyValueStore $nextHandler) 
    { 
 $this->_nextHandler = $nextHandler; 
    } 

    public function getEscaped($key) 
    { 
 return htmlentities($this->get($key), ENT_NOQUOTES, 'UTF-8'); 
    } 


// Client code 
$store = new SlowStore(array('pd' => 'Philip K. Dick', 
 'ia' => 'Isaac Asimov', 
 'ac' => 'Arthur C. Clarke', 
 'hh' => 'Helmut Heißenbüttel')); 
// in development, we skip cache and pass $store directly to FrontEnd 
$cache = new InMemoryKeyValueStore($store); 
$frontEnd = new FrontEnd($cache); 

echo $frontEnd->get('ia'), "
"; 
echo $frontEnd->getEscaped('hh'), "
";

PHP責任チェーン設計モデルのいくつかの実現説明について:◆責任チェーンはすでに対象図に存在する可能性があり、複合モデルの例と同じである.
◆また、Handler抽象は存在するか、存在しないか、最良の選択は、handleRequest()操作しか実行できない別々のHandlerインタフェースであり、1つのチェーンが1つの階層にしか存在しないことを強制しないことである.
◆抽象クラスを導入することもできるが、リクエスト処理は直交注目であるため、具体的なクラスは他のクラスを継承している可能性がある.
◆constructorまたはsetterによって、Clientまたは前のHandlerにHandler(または次のHandler)が注入される.
◆要求オブジェクトは通常ValueObjectであり、Flyweightとして実装されることもあります.PHPではstringのようなスカラータイプである可能性があります.stringは一定のValueObjectであることに注意してください.
簡単な総括責任チェーンモードは、一連のクラス(classes)で要求requestを処理しようとするが、これらのクラス間は緩やかな結合であり、唯一の共通点は彼らの間でrequestを伝達することである.すなわち,要求が来て,Aクラスが先に処理し,処理しなければBクラスに処理し,処理しなければCクラスに処理し,そのままチェーンのように伝達する.