Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 为什么我会对一个装饰师使用责任链?_Oop_Design Patterns_Decorator_Chain Of Responsibility - Fatal编程技术网

Oop 为什么我会对一个装饰师使用责任链?

Oop 为什么我会对一个装饰师使用责任链?,oop,design-patterns,decorator,chain-of-responsibility,Oop,Design Patterns,Decorator,Chain Of Responsibility,我只是在阅读模式,我很难想象一个场景,当我更喜欢它的使用而不是 你觉得怎么样?CoR有利基用途吗?我认为责任链是装饰师的一种特殊形式。我可以想到两种情况: 您没有核心对象,也就是说,在请求通过所有层/过滤器后,您不知道如何处理该请求。(类似于拦截器链这样的方面,它并不真正关心请求的结束) 您需要有选择地对请求应用一些预处理或后处理。不像装饰师那样以一般的增强形式。i、 过滤器可能会也可能不会处理一个特定的请求,但是添加一个装饰器总是会增强你的对象的某些功能 现在想不出更多,希望听到更多关于这

我只是在阅读模式,我很难想象一个场景,当我更喜欢它的使用而不是


你觉得怎么样?CoR有利基用途吗?

我认为责任链是装饰师的一种特殊形式。

我可以想到两种情况:

  • 您没有核心对象,也就是说,在请求通过所有层/过滤器后,您不知道如何处理该请求。(类似于拦截器链这样的方面,它并不真正关心请求的结束)
  • 您需要有选择地对请求应用一些预处理或后处理。不像装饰师那样以一般的增强形式。i、 过滤器可能会也可能不会处理一个特定的请求,但是添加一个装饰器总是会增强你的对象的某些功能
现在想不出更多,希望听到更多关于这个话题的内容。

Chain

避免耦合请求的发送者 通过提供超过 一个物体有机会处理 要求连锁接收对象 并沿链传递请求 直到一个对象处理它

vs

装饰师

附加额外责任 动态地创建对象。装饰师 提供一个灵活的替代方案 用于扩展的子类化 功能


我想说的是事情发生的顺序。如果将它们链接,则将沿着该链调用。对于decorator,您不能保证此顺序,只能附加额外的责任。

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

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

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


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

您可以在任何一点打破链条这一事实将责任链模式与装饰者模式区分开来。可以将装饰器看作是一次执行所有的装饰器,而不与其他装饰器进行任何交互。链中的链接可以被认为是一次执行一个链接,因为它们都依赖于前一个链接

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

当我使用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装饰师的引用

所有吠叫动物在进食前也会吠叫一次,这改变了现有的功能,因此类似于COR。但其目的与COR不同,即在众多动物中找到一种会吃食物的动物。这里的目的是修改行为

你可以想象一个COR被用来寻找一个人带着动物去散步。这可以实现为一个链表,如上面的
chained
,或一个显式列表。。。或者别的什么

希望这是相当清楚的


约翰

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

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


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

我认为应用这两种模式的情况是不同的。顺便说一下,对于decorator模式,decorator应该知道它所包装的组件
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);
}