为什么我会用装饰者的责任链?

我只是阅读责任链模式,我很难想象一个场景,我宁愿将它用于装饰器。

你怎么看? CoR是否有利基用途?


事实上,你可以在任何时候打破链条,将责任链模式与装饰者模式区分开来 。 装饰者可以被认为是在不与其他装饰者进行任何交互的情况下一次全部执行。 链中的链接可以被认为是一次执行一个,因为它们每个都依赖于前一个链接。

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

当我使用Win32 API时,有时需要使用它提供的挂钩功能。 挂钩Windows消息大致遵循责任链模式。 当你挂钩一条消息如WM_MOUSEMOVE时,你的回调函数将被调用。 将回调函数看作链中的最后一个链接。 链中的每个链接都可以决定是否丢弃WM_MOUSEMOVE消息或将其传递到下一个链接。

如果在该示例中使用了装饰器模式,则会收到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上面的链接列表或者作为一个明确的List ...或者其他任何东西来实现。

希望这是相当清楚的!

约翰


通过给予多个对象机会来处理请求,避免将请求的发送者耦合到其接收者。 链接接收对象并沿着链传递请求,直到对象处理它为止。

VS

装饰

动态地将附加职责附加到对象。 装饰器为扩展功能提供了子类化的灵活替代方案。

我会说它会围绕事情发生的顺序。 如果你把它们连起来,就会沿着链条被调用。 有了装饰者,你不能保证这个订单,只能附加额外的责任。

链接地址: http://www.djcxy.com/p/76547.html

上一篇: Why would I ever use a Chain of Responsibility over a Decorator?

下一篇: JSF Controller, Service and DAO