【问题标题】:Chain of responsibility: loop or next?责任链:循环还是下一个?
【发布时间】:2013-12-03 14:52:43
【问题描述】:

我正在实施责任链模式。

我有可以组合在一个列表中的不同策略,并且我有一个处理策略列表的处理器。每个策略都可以处理 CustomInput,并且可以选择是否也应处理其余策略。

interface Policy {    
  public boolean process(CustomInput input);    
}

interface Processor {    
  public void process(List<Policy> policies, CustomInput input)    
}

我打算实现处理器循环遍历策略列表并检查每个策略的布尔结果以了解是否继续执行其余策略。

我的同事建议将下一个 Policy 传递给每个 Policy,并让他们调用(或不调用)下一个 Policy(例如 FilterChain 所做的)。

我的问题如下:

在第二种解决方案(将下一个策略传递给当前正在处理的策略)中,与循环每个策略并检查其结果相比,我没有看到任何好处吗?

【问题讨论】:

  • 在第一种情况下,顶级运营商负责应用所有策略。在第二种情况下,每个策略必须知道它的子策略并且可以决定是否应用它。这取决于您将责任放在哪里来应用这些政策。
  • 在某些情况下,这样的模式会成为开销,也应该考虑到这一点。虽然 CoR 很好用,但不要忘记 KISS。有案例,有案例要考虑。
  • @Matheus,就我而言,我确实需要它(策略列表来自另一个服务的某个地方,并且处理代码不知道它们在做什么,只有在它可以继续之前必须处理它们下一步)。
  • 除非有目的,否则将迭代和选择步骤与处理步骤耦合似乎是不必要的耦合。

标签: java design-patterns chain-of-responsibility


【解决方案1】:

你能不能实现一个中途解决方案,让两个组件都有部分控制权?

interface Policy {
  public Policy process(CustomInput input, Policy defaultNext);
}

process 可以默认返回 defaultNext,除非它有自己的选择。

【讨论】:

  • 每个流程实现都需要“Policy next(Policy)”步骤吗?当“进程”拒绝并输入并重新发送到“默认下一个”时需要这样做:必须为发送选择一个新的“默认下一个”。
【解决方案2】:

传递下一个的想法对我来说毫无意义。所以我想要一个链:

A - B - C - D

C 如何知道 D?如果它在 C 的代码中,那么对链的任何更改都将是一个巨大的麻烦。

链需要遵循一些已经存在的其他路径,例如响应者在向其各自的父级提出帮助请求时会这样做(四人帮中的示例),或者您需要构建链,这就是为什么在 Go4 部分的底部,他们提到复合模式是自然发生的帮凶。

另请注意,执行责任链的主要原因之一是可能对项目进行操作的类型不同。这使得用 Java 接口实现它是完美的。

回答你的主要问题:在这种情况下使用责任链的好处有两个:1. 你不是在制造一个知道实现目标可能发生的所有事情的上帝对象(成功构建a Policy),和 2. 你不必输入很多丑陋的检查代码来查看你何时到达终点,因为无论谁处理它,不调用它的继任者,都会提示完成的项目的返回。

【讨论】:

  • 我倾向于同意 Rob 的观点,我不喜欢政策必须了解其他政策这一事实。我宁愿让它们易于实施,独立于其他的。
【解决方案3】:

我正在实施责任链模式。

不是真的。您同事的建议实际上是 GoF 如何定义责任链。

链中的第一个对象接收请求并处理它或将其转发给链上的下一个候选对象,这同样...链上的每个对象共享一个通用接口来处理请求和访问其后继者。 (第 224 页)

责任链可以简化对象互连。它们不是维护对所有候选接收者的引用,而是保留对其后继者的单个引用。 (第 226 页)

很明显,CoR 被定义为一个单链表。你所描述的更像是中介者模式,你的Processor扮演中介者的角色。权衡是集中控制还是分散控制。

它集中控制。 中介者模式用交互的复杂性换取中介者的复杂性。因为中介者封装了协议,所以它可能比任何单独的同事都复杂。这会使调解器本身成为难以维护的整体。 (第 277 页)

如果您确信Processor 只会遍历列表并检查布尔值,那么我认为您的设计是合理的。危险在于Processor 可能会获得与特定CustomInputPolicy 相关的“特殊”逻辑。这是神级的滑坡。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-26
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 2020-02-08
    • 1970-01-01
    相关资源
    最近更新 更多