1. Pattern definition
The responsibility chain pattern links the requested object to a chain, passing the request along the chain until there is an object processing the request, which allows multiple objects to have the opportunity to process the request, thus avoiding the coupling between the sender and the recipient of the request.
The responsibility chain pattern in the reality uses many, common is the OA system the workflow.
2. UML class Diagram
3. Sample Code
request.php
handler.php
Successor) {$this->successor = $handler; } else {$this->successor->append ($handler); }}/** * Processing Request * * This approach by using a template method pattern ensures you subclass Won't forget to call the successor. Besides, the returned * Boolean value indicates you if the request has 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; }/** * Each processor-specific implementation class will implement this method to process the request * * @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_exist S ($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_exist S ($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 of the IT proves/to is a bad idea. What if the value is "false"? return true; }} return false; }}
4. Test code
tests/chaintest.php
Chain = new Faststorage (Array (' bar ' = ' baz ')); $this->chain->append (The 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\behavio Ral\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 have no ' foo ' key, the slowstorage is responding $className = ' Designpatterns\behavioral\chainofrespo Nsibilities\responsible\slowstorage '; $this->assertequals ($className, $request->fordebugonly); }/** * @dataProvider makerequest */Public Function testfailure ($request) {$request->key = ' k Urukuku '; $ret = $this->chain->handle ($request); $this->assertfalse ($ret); The last responsible: $className = ' designpatterns\behavioral\chainofresponsibilities\responsible\slowstorage '; $this->assertequals ($className, $request->fordebugonly); }}
5. Summary
The main advantage of the responsibility chain model is that it can reduce the coupling degree of the system, simplify the mutual connection of objects, and enhance the flexibility of assigning responsibilities to the object, and it is convenient to add new request processing classes, the main disadvantage is that the request must be received, and for the long chain of responsibility, the processing of the request may involve multiple processing objects. System performance is affected and is not convenient for code debugging.