This is the 7th day of my participation in the August Text Challenge.More challenges in August


I want to learn the chain of responsibility pattern of design patterns

Definition: Multiple objects have the opportunity to process the request, thus decoupling the sender and receiver. These objects are connected in a “chain structure,” with each node forwarding requests until an object handles them.

The main idea: The requester does not need to know which node object is handling the request. If the termination criteria are not currently met, the request is forwarded to the next node for processing.


What is the “responsibility chain model”?

The chain of responsibility pattern defines that multiple objects have the opportunity to process the request, thus decoupling the sender and receiver. These objects are connected in a “chain structure,” with each node forwarding requests until an object handles them.

The core idea is that the requester does not need to know which node object is handling the request. If the termination criteria are not currently met, the request is forwarded to the next node for processing.

When the requirement is “pass-through” in nature (one such example in the code is multiple if, else if, else if, else else nested), you can consider splitting each branch into a node object and splicing it into a chain of responsibilities.


Advantages and Costs

Advantages:

  • You can add/remove node objects to the responsibility chain as required
  • There is no fixed “start node” and you can start at any node

Cost: The biggest cost of the chain of responsibility is the extra cost of each node. When the chain of responsibility is too long, many nodes serve only as pass-throughs rather than actual logic processing.

When should we use the chain of responsibility model?

When designing the system, pay attention to distinguish the primary and secondary, that is, which part is the core flow, which part is the auxiliary flow, whether the auxiliary flow has N if… if… if… If there is a unified abstraction for each IF, then the process of abstraction AIDS, and each IF is called as a responsible object in a chain, elegant implementation, easy to reuse and extensible.


Code implementation

To facilitate the demonstration, the common Log printing scenario is simulated. Three levels of log output are simulated:

  • LogHandler: Common logs
  • WarnHandler: Warning log
  • ErrorHandler: Error log

First we construct the “chain of responsibility” : LogHandler -> WarnHandler -> ErrorHandler. The LogHandler acts as the starting node of the chain.

If it is a normal log, LogHandler processes it and stops propagation. If logs are of a Warn level, the LogHandler is automatically passed down, and WarnHandler receives and processes the logs, stopping propagation. The same applies to error-level logs.

public class Study { public void study(PreparationList preparationList) { if (preparationList.isWashHair()) { System. The out. Println (" face "); {} the if (preparationList isWashHair ()) System. The out. Println (" shampoo "); {} the if (preparationList isHaveBreakfast ()) System. The out. Println (" breakfast "); } system.out.println (" I can go to school! ") ); } } public abstract class AbstractPrepareFilter { private AbstractPrepareFilter nextPrepareFilter; public AbstractPrepareFilter(AbstractPrepareFilter nextPrepareFilter) { this.nextPrepareFilter = nextPrepareFilter; } public void doFilter(PreparationList preparationList, Study study) { prepare(preparationList); if (nextPrepareFilter == null) { study.study(); } else { nextPrepareFilter.doFilter(preparationList, study); } } public abstract void prepare(PreparationList preparationList); } public class WashFaceFilter extends AbstractPrepareFilter { public WashFaceFilter(AbstractPrepareFilter nextPrepareFilter) { super(nextPrepareFilter); } @Override public void prepare(PreparationList preparationList) { if (preparationList.isWashFace()) { System. The out. Println (" face "); }}}Copy the code

\