Design mode series responsibility chain mode

Posted by sr20rps13 on Sun, 30 Jan 2022 16:18:47 +0100

Responsibility chain model

Chain of responsibility pattern: a chain of receiver objects is created for the request. This mode gives the type of request and decouples the sender and receiver of the request. This type of design pattern belongs to behavioral pattern.

The above explanation is very obscure. To put it bluntly, I just can't understand it. Let me talk about human words.

Examples

Example: our normal request is like a pile of sundries, such as rice, eggs, children's milk powder and a lump of shit. If our customers want to cook, they must first filter out eggs, milk powder and feces, right. After all, it's not an old eight... Sorry, I didn't mean to slander here.

To realize the above requirements in the fastest way, we can use the if statement:

  • Simulate incoming requests

    public class Request {
        // Requested data
        private String data;
        public String getData() {
            return data;
        }
        public void setData(String data) {
            this.data = data;
        }
    }
    
  • Next, use if to write the filter

public class Handler {
    public void handlerRequest(Request request) {
        // Get the requested data
        String data = request.getData();

        if (data.contains("egg")) {
            filterEgg(data);
        }
        if (data.contains("Baby milk powder")) {
            filterDrunk(data);
        }
        if (data.contains("Shit")) {
            filterShit(data);
        }       
    }
    private void filterShit(String data) {
        //doSomething
    }
    private void filterDrunk(String data) {
        //doSomething
    }
    private void filterEgg(String data) {
        //doSomething
    }
}

Well, the demand is written in if, and then one day I asked for more sweet potatoes, noodles and potato chips,

Then we have to go inside and add more if. After a long time, the code written is hard to maintain,

The code is like shit, which obviously doesn't meet our needs of object-oriented and decoupling.

We should extract each processing method into a class, and each class performs its own duties.

Whether it's filtering dog shit, eggs or 7788, what you do is filtering.

We can abstract it into an interface. So we have one interface and multiple implementation classes.

Realize the responsibility chain

  • First write a filter function interface to let all filters inherit the basic functions, and then implement the required filters.
public interface Filter {
    void doFilter(String data);
}
class FilterEgg implements Filter{
    @Override
    public void doFilter(String data) {
        List<String> strings = Arrays.asList(data.split(","));
        boolean egg = strings.contains("egg");
        if (egg){ System.out.println("Filtered eggs~");}
    }
}
class FilterDrunk implements Filter{
    @Override
    public void doFilter(String data) {
        List<String> strings = Arrays.asList(data.split(","));
        boolean drunk = strings.contains("drunk");
        if (drunk) {System.out.println("Filtered milk powder~");}
    }
}
class FilterShit implements Filter{
    @Override
    public void doFilter(String data) {
        List<String> strings = Arrays.asList(data.split(","));
        boolean shit = strings.contains("shit");
        if (shit){ System.out.println("Filtered shit~"); }
    }
}
  • Write a filter chain to put all the filters
public class FilterChain {
    List<Filter> filters = new ArrayList<>();
    public FilterChain() {
        filters.add(new FilterEgg());
        filters.add(new FilterShit());
        filters.add(new FilterDrunk());
    }
    public void processData(String data){
        for (Filter filter : filters) {
            filter.doFilter(data);
        }
    }
}

  • Put the request into the filter chain
public class Handler {
    public void HandlerRequest(Request request){
        String data = request.getData();
        FilterChain filterChain = new FilterChain();
        filterChain.processData(data);
    }
}
  • Simulate a request submitted to the filter chain
public class Request {
    private String  data;
    public String getData() {
        return data;
    }
    public void setData(String data) {
        this.data = data;
    }
    public Request(String data) {
        this.data = data;
    }
}
  • Finally, write a class to test
public class testHandRequest {
    public static void main(String[] args) {
        Request request = new Request("egg,chicken,mi,drunk,shit");
        Handler handler = new Handler();
        handler.HandlerRequest(request);
    }
}

The file directory structure is as follows:

Next, why use the responsibility chain model

Let's review what I did:

  • The if of each filtering process is abstracted into a class.
  • The filters are strung together using a filter chain.
After all, what did I do? I'll extract the if used for filtering and implement it with a class

Why?

  • Because this can make the filtering process more clearly divided, decoupled and easy to maintain.
  • Adding a specific Handler processing class will not affect the code of BaseHandler.

Disadvantages:

  • Adding a specific Handler processing class will not affect the code of BaseHandler.

  • It's not easy to debug and read the code at first glance. (external is just a doChain method,

    It is composed of multiple processing classes, depending on the corresponding call order).

Topics: Java Design Pattern filter