简体   繁体   中英

Is the Chain of Responsibility pattern a good replacement for a sequence of conditions?

When you need to execute a sequence of actions in a particular order, is the Chain of Responsibility pattern a good replacement for a sequence of conditions? Is it a good idea to replace a simple method with conditions like this:

public class MyListener implements MyHttpListener {

    // if false, the request will be thrown away and subsequent listeners will not be notified
    @Override
    public boolean onHttpRequestSend(HttpMessage msg) { 
        // handlers can change msg

        boolean isA = handleA(msg);
        if (isA) return false;

        boolean isB_notA = handleB(msg);
        if (isB_notA) return false;

        boolean isC_notA_notB = handleC(msg);
        if (isC_notA_notB) return true;

        ...

        throw new IllegalStateException();
    }
}

Now replace it with an implementation of the Chain of Responsibility pattern:

public class MyListener implements MyHttpListener {
    @Override
    public boolean onHttpRequestSend(HttpMessage msg) {
        ProcessingStep first = new StepA()
        ProcessingResult result = first.process(new ProcessingResult(msg, true));
        return result.returnValue;
    }
}

public interface ProcessingStep {
    ProcessingResult process(ProcessingResult stepResult);
}

public class ProcessingResult {
    HttpMessage message;
    boolean returnValue;
}

public class StepA implements ProcessingStep {
    @Override
    public ProcessingResult process(ProcessingResult stepResult) {
        if (handleA()) {
            return stepResult;
        }
        else {
            return new StepB().process(stepResult);
        }
    }
}   
public class StepB implements ProcessingStep {
    @Override
    public ProcessingResult process(ProcessingResult stepResult) {
        return stepResult; // this is the last step
    }
}

Your implementation of Chain of Responsibility pattern is not an exact implementation, as typically each element of the chain of handlers must be unaware of what coming next.

However, let's look at the major benefit of the CoR pattern: it enables to dynamically change the chain of handlers at runtime (which may not be available in hard-coded series of conditions). So, if you need the dynamic behavior of CoR pattern, you can benefit from it, but if not, it can be considered an unnecessary over-engineered solution.

The Chain of Responsibility is meant for the exact scenario that you are describing, ie, replacing a chain of if ... else with one call that handles your request (wrapped in the msg in your example).

So the answer is: Yes, your second code is a good replacement of your first code.


Whether you should replace your first piece of code with the second one is another question. For a code as simple as the one you currently have, adding a Design Pattern may be an overkill. The supplementary reasons for using this pattern are:

  • Dynamic arrangement of the if ... else blocks;
  • Adding new processing blocks;
  • Repurposing the handlers as dispatchers , capable of sending out the msg in a variety of directions, forming a Tree of Responsibility .

  • If your situation seems like it demands a Design Pattern, go ahead.
  • If it doesn't, leave it.
  • If you are in doubt, add the pattern for now. If in future you see you/your teammates getting confused about your code, remove it at that time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM