Behavioral patterns (eight) duty chain (Chain of Responsibility)

Motivation (Motivate)

   In the software building process, request a plurality of objects may be processed, but only one receiver each request at run time, if the display is specified will be necessary to bring the tight coupling of the recipient's request. How to make the sender of the request need not specify a specific recipient, so that the recipient's request decide to process the request at run-time, so that both decoupled.

Intent (Intent)

   Avoid requesting the sender and receiver are coupled together, so that a plurality of objects are likely to accept the request, the connection objects form a chain, and the request is transmitted along the chain, there are known so far object handles it. - "Design Patterns" GoF

FIG structure (Structure)


Composition mode

    It can be seen in the following roles duty chain configuration diagram of: (1) the role abstraction (Handler) : abstraction interface to define a processing request, which is generally designed as an abstract class, because of the different specific processing different processing request by the way, which therefore defines an abstract request processing method. Because each of the next house or a handler handler, thus defining an object type in a self-abstraction who, as a reference to the home. By this reference, the process may even as a chain.     (2), specific processing role (ConcreteHandler) : specific handler is a subclass of abstract handlers, it can handle the user request, it implements the abstract processing method Abstract handler defined in the particular handler class, the processing request before require a judgment to see if there is a corresponding processing authority, if the request can be processed on the handling of it, or forwards the request to the successor; access to the next object in the chain handler in particular, in order to request forwarding.
   

Chain of Responsibility pattern of code implementation

    In real life, examples of chain of responsibility pattern is a lot of, for example,: leave the company is a good example of the process chain of responsibility pattern, if a half-day leave, just tell the department manager on it; if leave seven days or more personnel must be approved by the Superintendent; leave if more than 15 days, it would have to go through the approval of the president. There are similar example is the procurement process, the process is also the duty chain well represented, different amounts of procurement, personnel require approval are also different, such as: paper sector procurement of $ 10,000, as long as the department heads to sign and ratify Yes, if you want to purchase greater than 10,000 less than 50,000 items, it would need financial managers issuing process, and if the procurement of raw materials, or 300,000 items, it would need to president or a similar role to the approval. Then we have to purchase an example to illustrate the chain of responsibility pattern. Codes are as follows:

static  void the Main ( String [] args) 
{ 
    PurchaseRequest requestDao = new new PurchaseRequest ( 8000.0 , " single-pole 5 " ); 
    PurchaseRequest requestHuaJi = new new PurchaseRequest ( 10000.0 , " 10 put Fangtianhuaji " ); 
    PurchaseRequest requestJian = new new PurchaseRequest ( 80000.0 , " 5 gold Dragonscale lightning split " ); 

    the Approver Manager = new new Manager ( " Once Upon "); 
    The Approver Financial = new new FinancialManager ( " Huang Qi England " ); 
    the Approver CEO = new new the CEO ( " 13th Aunt " ); 

    // set duty chain 
    manager.NextApprover = Financial; 
    financial.NextApprover = CEO; 

    // process the request 
    manager.ProcessRequest (requestDao); 
    manager.ProcessRequest (requestHuaJi); 
    manager.ProcessRequest (requestJian); 

} 
// purchase request 
public  Sealed  class PurchaseRequest 
{ 
    // amount
    public  Double Amount { GET ; the SET ;} 

    // product name 
    public  String ProductName { GET ; the SET ;} 

    public PurchaseRequest ( Double AMOUNT, String productName) 
    { 
        Amount = AMOUNT; 
        ProductName = productName; 
    } 
} 

// abstract approver, Handler- - the equivalent of "abstraction role" 
public  abstract  class the approver 
{ 
    // the next approver, thus forming a chain 
    public{NextApprover the Approver GET ; SET ;} 

    // approvers name 
    public  String the Name { GET ; SET ;} 

    public the Approver ( String name) 
    { 
        the this .Name = name; 
    } 

    // processing request 
    public  abstract  void the ProcessRequest (PurchaseRequest Request); 
} 

// manager ---- equivalent to "specifically address the role" ConcreteHandler 
public  Sealed  class Manager: the Approver 
{ 
    public Manager ( String name): Base(name) {} 

    public  the override  void ProcessRequest (PurchaseRequest Request) 
    { 
        IF (request.Amount <= 10000.0 ) 
        { 
            Console.WriteLine ( " {0} manager for raw materials procurement plan approved {1}! " , the this .Name , request.ProductName); 
        } 
        the else  IF ! (NextApprover = null ) 
        { 
            NextApprover.ProcessRequest (Request); 
        } 
    } 
} 

// Finance manager --- equivalent to "specifically address the role" ConcreteHandler 
public  Sealed  class FinancialManager: the Approver
{
     public FinancialManager ( String name): Base (name) {} 

    public  the override  void the ProcessRequest (PurchaseRequest Request) 
    { 
        IF (request.Amount> 10000.0 && request.Amount <= 50000.0 ) 
        { 
            Console.WriteLine ( " {0} approved financial manager ! {1} for raw materials procurement plan " , the this .Name, request.ProductName); 
        } 
        the else  IF ! (NextApprover = null ) 
        { 
            NextApprover.ProcessRequest (Request); 
        } 
    } 
}

// President --- equivalent to "specifically address the role" ConcreteHandler 
public  Sealed  class CEO: the Approver 
{ 
    public CEO ( String name): Base (name) {} 

    public  the override  void ProcessRequest (PurchaseRequest Request) 
    { 
        IF (request.Amount> 50000.0 && request.Amount < 300000.0 ) 
        { 
            Console.WriteLine ( " {0} president approved a plan to purchase raw materials {1}! " , the this .Name, request.ProductName); 
        } 
        the else 
        { 
            Console.WriteLine ( " Amount of the procurement plan is relatively large, need a board meeting to discuss the decision! " ); 
        } 
    } 
}

Points realization chain of responsibility pattern:

        Chain of Responsibility pattern of applications is "a request may have multiple recipients, but in the end only the true recipient of a" couple only the sender and the recipient of this request when possible a "change vulnerability" symptoms, the purpose of the chain of responsibility is to decouple the two, in order to better respond to change.
  After application of the Chain of Responsibility pattern duties as assigned object will be more flexibility. We can dynamically add / change request processing functions at runtime.
  When we want to add a DHandler process the request, and then you do not need to change the original code, and to comply with the open closed principle. This change gives our program more and more resistant to change. Handler class itself inherits from BaseHandler type, but also contains a BaseHandler type of objects, this is similar to the Decorator pattern.
  If the request is passed to the end of the chain of responsibility is still not addressed, there should be a reasonable default mechanism. It is also accepted responsibility for each object, rather than the responsibility of issuing the request object.

(1) The main advantage of duty chain are:

        1], decouple: duty chain such that an object need not know which other objects handle their requests. Target only knows that the request can be processed, the recipient and the sender are not each other's clear message, and the chain object does not need to know the structure of the chain, have created client is responsible for the chain.
        2], interconnected objects simplified: only the receiver to maintain a reference to the object of its successors, without the need to maintain all its reference candidate handlers.
        3], to enhance the flexibility of the object assigned duties: When the object to assign duties, responsibilities chain can bring more flexibility to us. It may function through the increase or even dynamically modified at runtime processing of a request.
        4], adding a new request handler class is easy: add a new request handler without modifying the original system of code in the system, you only need to re-build the chain to the client, this point of view is in line with "open closed principle ".

(2) The main drawback of duty chain are:

        1], before finding the right treatment object, all conditions must be judged executed again, when the chain of responsibility is too long, it may cause performance problems.
        2], may lead to a request is not processed.
        3], the chain assembly requires the client, the client coupling structure and composition of the chain, can be mentioned the outside of the combined action of the client, by arranging to do, the point will be better.

(3), in the following case may be considered to use duty chain:

        1] the case of approval, the system requires a plurality of objects to complete the treatment, for example leave systems.
        2], when a plurality of if-else statement code, this time can be considered to use Chain of Responsibility pattern to reconstruct the code
        3], there are a plurality of the same object can process the request, the request which specific object processing has run time automatically determined. The client simply requests submitted to the chain, the request to be processed without concern for who and how it is handled.
        4], without explicitly specified recipient to submit a request to a plurality of objects. Sender of the request and decoupling the requester, the request will be passed along the chain, the response handler sought.
        5], a set of objects may be dynamically assigned to process the request. The client can dynamically create a chain of responsibility to handle the request, it can also dynamically change the order between the handler chain

Implement .NET chain of responsibility pattern

     This mode is not much to achieve in the Net framework, I feel more of this model is the use of scenarios in business systems will always have greater usefulness. This mode is used when processing the message UI, but actually Windows message loop or hard coded configuration. Because of the efficiency considerations, Windows message loop which objects have a request, directly to the address of the handler. If the object in the chain more, and the function of the real part of the process, is inefficient at the chain. We therefore more suitable for business processes when using this mode, that is more common on the performance requirements are not particularly high.

Guess you like

Origin www.cnblogs.com/springsnow/p/11359376.html