我只是在阅读“责任链”模式,想像一个场景而不愿意使用装饰器,我很难想象。
你怎么看?CoR有利基用途吗?
OrderCompleter.Complete()
但它可能是这样的:“如果打印服务响应ping并且此订单或父订单尚未打印,并且下达订单的客户未直接集成用我们的系统。”
Answers:
您可以随时中断链的事实将“责任链”模式与“装饰者”模式区分开。可以将装饰器视为一次执行所有操作,而无需与其他装饰器进行任何交互。链中的链接可以一次执行一个,因为它们每个都依赖于上一个链接。
当您可以将程序概念化为由链接组成的链时,请使用“责任链”模式,其中每个链接可以处理请求或将请求向上传递。
当我以前使用Win32 API时,有时需要使用它提供的挂钩功能。挂钩Windows消息大致遵循“责任链”模式。当您钩住WM_MOUSEMOVE之类的消息时,将调用您的回调函数。将回调函数视为链中的最后一个链接。链中的每个链接都可以决定是丢弃WM_MOUSEMOVE消息,还是将其沿链向上传递到下一个链接。
如果在该示例中使用了Decorator模式,则将已收到WM_MOUSEMOVE消息的通知,但您将无力阻止其他钩子也对其进行处理。
在游戏引擎中使用了“命令链”模式的另一个地方。同样,您可以挂钩引擎功能,事件和其他东西。对于游戏引擎,您不想简单地添加功能。您要添加功能并阻止游戏引擎执行其默认操作。
这些模式之间的区别与何时或如何断开链(假定为链)或何时执行额外行为无关。它们之间的联系在于,它们都使用合成来支持继承以提供更灵活的解决方案。
关键区别在于装饰器添加了新的行为,从而实际上扩展了原始接口。类似于普通扩展如何添加方法,只不过“子类”仅通过引用耦合,这意味着可以使用任何“超类”。
COR模式可以修改现有行为,类似于使用继承覆盖现有方法。您可以选择调用super.xxx()来继续执行“链”或自己处理消息。
因此,区别是微妙的,但是装饰器的示例应该有所帮助:
interface Animal
{
Poo eat(Food food);
}
class WalkingAnimal implements Animal
{
Animal wrapped;
WalkingAnimal(Animal wrapped)
{
this.wrapped = wrapped;
}
Position walk(Human walker)
{
};
Poo eat(Food food)
{
return wrapped.eat(food);
}
}
class BarkingAnimal implements Animal
{
Animal wrapped;
BarkingAnimal(Animal wrapped)
{
this.wrapped = wrapped;
}
Noise bark()
{
};
Poo eat(Food food)
{
bark();
return wrapped.eat();
}
}
您会看到我们可以组成步行,吠叫的动物……或者实际上增加了对任何动物吠叫的能力。要直接使用这种额外的行为,我们需要保留对BarkingAnimal装饰器的引用。
所有BarkingAnimal的食物在进食前也会吠一次,这改变了现有功能,因此类似于COR。但是其目的与COR不同,即从许多可以吃食物的动物中寻找一种。这里的目的是修改行为。
您可以想象使用COR来寻找将带走动物的人。可以将其实现为chained
上面的链接列表,也可以实现为显式列表...等等。
希望这是相当清楚的!
约翰
链
通过给一个以上的对象一个处理请求的机会,避免将请求的发送者耦合到其接收者。链接接收对象,并将请求沿着链传递,直到对象处理该请求。
与
装饰器
动态地将附加职责附加到对象。装饰器为子类提供了灵活的替代方案,以扩展功能。
我会说事情发生的顺序。如果您将它们链接起来,它们将沿着链接被调用。对于装饰器,您不能保证会获得此命令,只能承担其他责任。
装饰器
装饰器模式允许将行为动态添加到单个对象。
它提供了子类别的灵活替代方案,以扩展功能。即使使用继承,它也从最低公共分母(LCD)界面继承。
装饰器的UML图
后果:
有用的链接:
来自维基百科的Decorator_pattern
装饰从sourcemaking
责任链:
责任链模式是一种设计模式,由命令对象的源和一系列处理对象组成。每个处理对象都包含定义其可以处理的命令对象类型的逻辑。其余的传递给链中的下一个处理对象
UML图
在以下情况下,此模式更有效:
有用的链接:
维基百科的责任链模式
oodesign的责任链模式
来源链的责任链
真实示例:在公司中,指定角色对处理购买请求有特定的限制。如果具有指定角色的人员没有足够的权力来批准购买账单,则他会将命令/请求转发给拥有更多权限的继任者。该链将继续,直到处理命令为止。
在阅读了“四人帮”的定义之后,我不相信有真正的区别。(为方便起见包括)
Wikipedia充实了它们,但其中有些是任意的。
前两个属性并不能真正区分模式。后两者可以,但是通常实现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添加一行,如果您想要的只是放任自己,以防万一其他人弄糟了您的设计,但是为什么要碰碰运气呢?)
我认为应用这两种模式的情况是不同的。顺便说一下,对于装饰器模式,装饰器应该知道它包装的组件。对于CoR,不同的拦截器之间可能一无所知。