The model of responsibility chain in design mode---pattern chain-of-responsibility

Source: Internet
Author: User

Definition of a pattern

The responsibility chain pattern is defined as follows:

Avoid coupling the sender of a request to their receiver by giving + than one object a chance to handle the request. Chain the receiving objects and pass the request along the Chain until an object handles it.

Enables multiple objects to have the opportunity to process requests, thus avoiding the coupling between the sender and the recipient of the request. Link the objects together and pass the request along the chain until an object is processed by them.

Type

Behavior Class

Usage Scenarios for patterns

A request can be handled by multiple handlers or the processor does not explicitly refer to timing

Introduction to UML class diagram roles

Handler class-Abstract processor class,
The abstract processing class implements three responsibilities:
One is to define a request processing method Handlermessage, the only way to open the door
The second is to define a chain of compile method Setnext, set the next processor
The third is to define the method that the specific processor must implement: Gethandlerlevel and Echo

Concretehandler Class-specific processor class
Implement several specific processor classes to form a chain that processes messages

The common source of the pattern

Abstract Processor-handler:

 Public Abstract classHandler {PrivateHandler Nexthandler;//Set who is the next processor     Public void Setnext(Handler Nexthandler) { This. Nexthandler = Nexthandler; }//Get level to process request    protected AbstractLevelGethandlerlevel();//Per processor logic for handling request    protected AbstractResponseEcho(Request request);//Each processor must process the request     PublicFinal ResponseHandlermessage(Request request) {Response Response =NULL;//Determine if you can handle it yourself        if(Request.getlevel (). GetId () = = (Gethandlerlevel (). GetId ()))            {response = echo (request); System. out. println ("Response:"+response); }Else{//Not the level of your own processing            //Determine if there is a next processor            if(Nexthandler! =NULL{response = Nexthandler.handlermessage (request); }Else{//response No handlersResponse =NewResponse ("Request does not handle"); System. out. println ("Response:"+response); }        }returnResponse }}

The abstract processing class implements three responsibilities:
One is to define a request processing method Handlermessage, the only way to open the door
The second is to define a chain of compile method Setnext, set the next processor
The third is to define the method that the specific processor must implement: Gethandlerlevel and Echo

Specific Processor:

ConcreteHandler1:

 Public  class ConcreteHandler1 extends Handler {    @Override    protectedLevelGethandlerlevel() {//TODO auto-generated method stub        return NewLevel (1); }@Override    protectedResponseEcho(Request request) {//TODO auto-generated method stubSystem.out.println ("ConcreteHandler1----echo:"+request);return NewResponse ("ConcreteHandler1---Echo:"+request); }}

ConcreteHandler2:

 Public  class ConcreteHandler2 extends Handler {    @Override    protectedLevelGethandlerlevel() {//TODO auto-generated method stub        return NewLevel (2); }@Override    protectedResponseEcho(Request request) {//TODO auto-generated method stubSystem.out.println ("ConcreteHandler2----echo:"+request);return NewResponse ("ConcreteHandler2---Echo:"+request); }}

ConcreteHandler3:

 Public  class ConcreteHandler3 extends Handler {    @Override    protectedLevelGethandlerlevel() {//TODO auto-generated method stub        return NewLevel (3); }@Override    protectedResponseEcho(Request request) {//TODO auto-generated method stubSystem.out.println ("ConcreteHandler3----echo:"+request);return NewResponse ("ConcreteHandler3---Echo:"+request); }}

Response class:

 Public  class Response {    protectedString responsestring; Public Response(String responsestring) {Super(); This. responsestring = responsestring; } PublicStringgetresponsestring() {returnresponsestring; } Public void setresponsestring(String responsestring) { This. responsestring = responsestring; }@Override     PublicStringtoString() {return "Response [responsestring="+ responsestring +"]"; }}

Level class:

 Public  class  level {    protected intId Public  Level(intID) {Super(); This. id = ID; } Public int getId() {returnId } Public void setId(intID) { This. id = ID; }@Override     PublicStringtoString() {return "level [id="+ ID +"]"; }}

Request class:

 Public  class Request {    protectedString restring;protectedLevel level; Public Request(String restring, level level) {Super(); This. restring = restring; This. level = level; } PublicLevelGetlevel() {returnLevel } Public void SetLevel(level) { This. level = level; } PublicStringgetrestring() {returnrestring; } Public void setrestring(String restring) { This. restring = restring; }@Override     PublicStringtoString() {return "Request [restring=]+ restring +", level="+ Level +"]"; }}

Client:

 Public classClient { Public Static void Main(string[] args) {//TODO auto-generated method stubRequest Request1 =NewRequest ("request_001",NewLevel (1)); Request Request2 =NewRequest ("request_002",NewLevel (2)); Request Request3 =NewRequest ("request_003",NewLevel (3)); Request Request4 =NewRequest ("request_004",NewLevel (4)); Handler H1 =NewConcreteHandler1 (); Handler H2 =NewConcreteHandler2 (); Handler H3 =NewConcreteHandler3 ();        H1.setnext (H2);        H2.setnext (H3);        Response response1 = H1.handlermessage (Request1); System. out. println ("------------------------------------------------------------------");        Response Response2 = H1.handlermessage (REQUEST2); System. out. println ("------------------------------------------------------------------");        Response response3 = H1.handlermessage (REQUEST3); System. out. println ("------------------------------------------------------------------");    Response Response4 = H1.handlermessage (REQUEST4); }}
Output results
ConcreteHandler1----Echo:Request[Restring=request_001, Level=level [id=1]]Response:Response[Responsestring=concretehandler1---Echo:Request[Restring=request_001, Level=level [id=1]]]------------------------------------------------------------------ConcreteHandler2----echo:Request[Restring=request_002, Level=level [id=2]]Response:Response[Responsestring=concretehandler2---Echo:Request[Restring=request_002, Level=level [id=2]]]------------------------------------------------------------------ConcreteHandler3----echo:Request[Restring=request_003, Level=level [id=3]]Response:Response[Responsestring=concretehandler3---Echo:Request[Restring=request_003, Level=level [id=3]]]------------------------------------------------------------------Response:Response[responsestring=Request  Do  notHandle
Advantages

Separating requests from processing: The requester can not know who is dealing with, the processor can also not know the requester, the two decoupling, improve the system flexibility.

Disadvantages

One is the performance issue:
Each request is traversed from the chain head to the end of the chain, especially when the chain is longer, performance is a relatively large problem
Second, debugging inconvenient:
Especially when the chain is long, the link is more, using a similar recursive way, debugging logic may be more complex.

Precautions:

The number of nodes in the chain needs to be controlled, to avoid the case of super long chain, the general practice is to set a maximum number of nodes in the handler, in the set Setnext method to determine whether the threshold is exceeded, the chain is not allowed to establish, to avoid the unconscious damage the performance of the system.

Model implementation reference in Android source code

(1). Design pattern of Zen-16th chapter responsibility Chain mode
(2) Responsibility chain mode
https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/ Chain-of-responsibility/aigestudio

The model of responsibility chain in design mode---pattern chain-of-responsibility

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.