责任链模式是否可以很好地替代一系列条件?
Is the Chain of Responsibility pattern a good replacement for a sequence of conditions?
当您需要按特定顺序执行一系列操作时,责任链模式是否可以很好地替代条件序列?用这样的条件替换一个简单的方法是个好主意吗:
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();
}
}
现在将其替换为责任链模式的实现:
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
}
}
您对 Chain of Responsibility 模式的实现不是一个精确的实现,因为通常处理程序链中的每个元素都必须不知道接下来会发生什么。
但是,让我们看看 CoR 模式的主要好处:它可以在运行时动态更改处理程序链(这在硬编码系列中可能不可用的条件)。所以,如果你需要 CoR 模式的动态行为,你可以从中受益,但如果不需要,它可以被认为是一个不必要的过度设计的解决方案。
Chain of Responsibility 用于您所描述的确切场景,即用一个处理您请求的调用替换 if ... else
链(包装在 msg
中你的例子)。
所以答案是:是的,您的第二个代码可以很好地替代您的第一个代码。
是否应该用第二段代码替换第一段代码是另一个问题。对于像您当前拥有的代码一样简单的代码,添加设计模式可能有点矫枉过正。使用此模式的补充原因是:
if ... else
块的动态排列;
- 添加新的处理块;
- 将处理程序重新用作调度员,能够向各个方向发送
msg
,形成责任树.
- 如果您的情况看起来需要设计模式,请继续。
- 如果没有,就离开。
- 如果您有疑问,请暂时添加模式。如果将来您看到 you/your 队友对您的代码感到困惑,请立即将其删除。
当您需要按特定顺序执行一系列操作时,责任链模式是否可以很好地替代条件序列?用这样的条件替换一个简单的方法是个好主意吗:
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();
}
}
现在将其替换为责任链模式的实现:
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
}
}
您对 Chain of Responsibility 模式的实现不是一个精确的实现,因为通常处理程序链中的每个元素都必须不知道接下来会发生什么。
但是,让我们看看 CoR 模式的主要好处:它可以在运行时动态更改处理程序链(这在硬编码系列中可能不可用的条件)。所以,如果你需要 CoR 模式的动态行为,你可以从中受益,但如果不需要,它可以被认为是一个不必要的过度设计的解决方案。
Chain of Responsibility 用于您所描述的确切场景,即用一个处理您请求的调用替换 if ... else
链(包装在 msg
中你的例子)。
所以答案是:是的,您的第二个代码可以很好地替代您的第一个代码。
是否应该用第二段代码替换第一段代码是另一个问题。对于像您当前拥有的代码一样简单的代码,添加设计模式可能有点矫枉过正。使用此模式的补充原因是:
if ... else
块的动态排列;- 添加新的处理块;
- 将处理程序重新用作调度员,能够向各个方向发送
msg
,形成责任树.
- 如果您的情况看起来需要设计模式,请继续。
- 如果没有,就离开。
- 如果您有疑问,请暂时添加模式。如果将来您看到 you/your 队友对您的代码感到困惑,请立即将其删除。