我为什么要对装修工使用责任链呢?

我只是阅读了 责任链模式,我有麻烦想象一个场景时,我更喜欢它的使用超过 装潢师

你怎么看? CoR 有利基用途吗?

32179 次浏览

我认为 责任链室内设计师的一种特殊形式。

我可以想到两种情况:

  • 您没有核心对象,也就是说,在请求通过所有层/过滤器之后,您不知道如何处理该请求。(类似于拦截器链这样的方面,它并不真正关心请求的结束位置)。
  • 您需要有选择地对请求应用一些预处理或后处理。而不是像装饰者那样以一般的增强形式。也就是说,过滤器可以处理特定的请求,也可以不处理,但是添加一个装饰器总是可以通过一些功能来增强对象。

现在想不到更多了,希望能听到更多关于这个话题的内容。

链子

避免耦合请求的发送方 给它的接收者超过 一个对象处理 请求。链接接收对象 然后沿着链传递请求 直到对象处理它。

室内设计师

附加额外的责任 一个动态的对象 提供灵活的选择 扩展子类化 功能。

我认为这是事情发生的顺序。如果你将它们链接起来,它们将沿着链接被调用。对于装饰者,你不能保证这个订单,只能附加额外的责任。

当您想要向对象添加功能时,可以使用 Decorator。

当许多参与者之一可能对一个对象采取行动时,就使用 COR。

根据类型调用 特别 Decorator 来执行操作; 而 COR 沿着定义的链传递对象,直到其中一个参与者确定操作完成。

当对不同处理程序进行多级升级时,可以使用 COR ——例如,在呼叫中心,客户对公司的价值决定呼叫是否到达特定的支持级别。

事实上,你可以在任何时候打破责任链,这使得责任链模式与修饰模式 有所不同。修饰符可以被认为是在没有与其他修饰符进行任何交互的情况下一次执行所有修饰符。链中的链接可以被认为是一次执行一个,因为它们每个都依赖于前一个链接。

当您可以将程序概念化为由链接组成的链时,可以使用责任链模式,其中每个链接可以处理请求或向上传递请求。

当我使用 Win32API 时,有时需要使用它提供的挂钩功能。挂接 Windows 消息大致遵循责任链模式。当您钩住一个消息(如 WM _ MOUSEMOVE)时,您的回调函数将被调用。可以将回调函数看作链中的最后一个链接。链中的每个链接都可以决定是抛弃 WM _ MOUSEMOVE 消息还是将其传递到链上的下一个链接。

如果在这个例子中使用了修饰模式,你会被通知到 WM _ MOUSEMOVE 消息,但是你无法阻止其他钩子处理它。

另一个使用命令链模式的地方是在游戏引擎中。同样,您可以钩住引擎函数、事件和其他东西。在游戏引擎的情况下,您不想简单地添加功能。您希望添加功能并阻止游戏引擎执行其默认操作。

我同意从结构的角度来看,这两种模式非常相似。我的想法是关于最终的行为:

在处理请求的 CoR 元素的经典解释中,它打破了链。

如果修饰符中的任何元素打破了链,那么它将是修饰符的 错了实现,因为基本的行为部分将丢失。装饰器的思想是在基本行为保持不变的情况下透明地添加新行为。

我认为应用这两种模式的情况是不同的。顺便说一下,对于修饰模式,装饰者应该知道它包装的组件。而对于 CoR 来说,不同的拦截器可能彼此一无所知。

  1. 关键字’扩展’-静态扩展。
  2. 修饰模式-动态延伸。
  3. 责任链模式-只是处理一个命令对象 一组处理对象,这些对象彼此不认识。

在阅读了“四人帮”的定义后,我不相信它们之间有真正的区别

  • Decorator: 允许动态包装对象,以修改它们现有的职责和行为
  • 责任链: 通过将接收对象链接在一起,为多个对象提供处理请求的机会

维基百科把它们充实了一点,但有些是随意的。

  • 装饰符通常作为链表实现。但我认为这个级别太低,不能被视为模式的“一部分”。
  • 责任链链接只处理责任范围内的数据,但是确定责任和数据处理都是行为的一部分。装饰者可以很容易地做到这一点。
  • Decorator 要求您调用委托。
  • “纯”CoR 链接应该只在不处理数据的情况下调用委托。

前两个属性并不能真正区分模式。后两者可以,但是 Decorator 和 CoR 通常的实现方式并不强制这些属性——设计者只是希望没有人编写一个 Decorator 来中断链接,或者编写一个 CoRLink 来在处理数据后继续链接。

要实际实现这些属性,您需要如下所示。

强制装修:

abstract class Decorated {


public Decorated delegate;


public final Object doIt(Object args) {
Object returnVal = behavior(arg);
if(delegate != null) returnVal = delegate.doit(returnVal);
return returnVal;
}


protected abstract Object behavior(Object args); //base or subclass behavior
}

强制责任链:

abstract class Link {


public Link delegate;


public final Object processIt(Obect args) {
Object returnVal = args;
if(isMyResponsibility) returnVal = processingBehavior(returnVal);
else returnVal = delegate.processIt(returnVal);
return returnVal;
}


protected abstract Boolean isMyResponsibility(Object args);


protected abstract Object processingBehavior(Object args);
}

(或者,您可以在 javadoc 中添加一行代码,如果您想要的只是免除自己的责任,以防其他人搞砸您的设计——但是为什么要听天由命呢?)

室内设计师

  1. Decorator 模式允许动态地将行为添加到单个对象中。

  2. 它为扩展功能提供了对 子分类的灵活替代。即使它使用继承,它也继承了最小公分母(LCD)接口。

装饰器的 UML 图

UML diagram for Decorator

后果:

  1. 通过装饰,还可以动态删除添加的功能。
  2. 装饰在运行时向对象添加功能,这将使调试系统功能更加困难。

有用连结:

何时使用修饰模式?

来自维基百科的 Decorator _ pattern

装饰者 来自源头制作

责任链:

责任链模式是一种设计模式,由一个命令对象源和一系列处理对象组成。每个处理对象都包含定义它可以处理的命令对象类型的逻辑; 其余的传递给链中的下一个处理对象

UML 图

enter image description here

这种模式在以下情况下更为有效:

  1. 多个对象可以处理一个命令
  2. 事先不知道接头人是谁
  3. 应该自动确定处理程序
  4. 它希望将请求发送给一组对象,而不显式地指定其接收方
  5. 必须以动态方式指定可以处理该命令的对象组

有用连结:

来自维基百科的责任链模式

来自 oodesign 的责任链模式

来自源头制造的责任链

现实中的例子: 在公司中,指定的角色对处理购买请求有特定的限制。如果指定角色的人没有足够的权力批准购货单,他将把命令/请求转发给有更大权力的继任者。此链将一直持续到处理完命令为止。