
preface
Many frameworks such as mybatis plug-ins, servlet filter, dubbo, and security frameworks such as Spring security and apache shiro all use the chain of responsibility pattern in the design pattern, so learning the chain of responsibility pattern becomes a good way to help you learn these frameworks. Today we will take a look at the responsibility chain model.
defined
If multiple handlers have the opportunity to process the data source (RequestSource, which is not just a database data source, but can be a request, in short, a source), the chain of responsibility can decouple the sender and receiver of the data, and the data is passed along the chain of responsibility until an object processes it.
It forms a chain of assembly lines, so it is called a chain of responsibility, but it is not limited to a chain, but can also be formed into a tree or a ring, depending on your business design.
scene
Plug-in design, interceptors, filters, etc. specific chain-processing for pointcuts. You can use the chain of responsibility model.
two implementations
The difference between the two methods is mainly the difference in the order and structure of the processing chain. Next, let's take a look at these three methods.
Defining the processing order through a collection of processors
The advantage is that processors can be managed centrally and the blame is single. Very easy to understand and easy to implement. The disadvantage is that if a new handler is added, it will inevitably affect the existing handler and can only be executed sequentially. The processing process is as follows:
Next, use code to implement this pattern:
HandlerChain is responsible for maintaining the order of the call chain. Here, the default implementation uses List to manage Handler
public interface HandlerChain {
/**
* Call handler to process source.
*
* @param requestSource the request source
*/
void doChain(RequestSource requestSource);
}
//Implement
public class DefaultHandlerChain implements HandlerChain {
//Current position of handler pointer
private int pos = 0;
private List<Handler> handlers = new ArrayList<>();
public void addHandler(Handler handler) {
handlers.add(handler);
}
@Override
public void doChain(RequestSource requestSource) {
int size = handlers.size();
if (pos < size) {
//Pay attention to the handling of pos
Handler handler = handlers.get(pos++);
handler.doHandler(requestSource, this);
}
}
}
Handler is the node abstraction of the processing chain and the specific processor of the data source (RequestSource). It is responsible for processing data and deciding whether to enter the next Handler.
public interface Handler {
/**
* Do handler.
*
* @param requestSource Data source
* @param handlerChain Pass in the current Chain to make a similar recursive call.
*/
void doHandler(RequestSource requestSource,HandlerChain handlerChain);
}
//One implementation
public class HeaderHandler implements Handler {
@Override
public void doHandler(RequestSource requestSource, HandlerChain handlerChain) {
//Processing data
Integer header = requestSource.getHeader();
System.out.println("header handler= " + header);
//Continue to the next one You can decide whether to continue the chain based on the conditions
handlerChain.doChain(requestSource);
}
}
Utilize the pointer nature of linked lists
This takes advantage of part of the characteristics of linked lists. By specifying the next Handler as a pointer in the current Handler, Handler is more autonomous and more flexible in processing nodes.
Handler is responsible for pointer and logical processing:
public interface Handler {
/**
* Pointer points to the next processing node.
*
* @return the next
*/
Handler getNext();
/**
* Handle specific logic.
*
* @param requestSource the request source
*/
void doHandler(RequestSource requestSource);
}
//Implement
public class HeaderHandler implements Handler {
private Handler next;
public HeaderHandler(Handler next) {
this.next = next;
}
@Override
public Handler getNext() {
return next;
}
@Override
public void doHandler(RequestSource requestSource) {
Integer header = requestSource.getHeader();
System.out.println("header = " + header);
if (next != null) {
next.doHandler(requestSource);
}
}
}
summary
Chain of responsibility models are very common in various common frameworks. Therefore, I suggest that you study this design model carefully.
Comments0