2009-04-14 42 views
60

我只是在阅读Chain of Responsibility的模式,我很难想象一个场景,我宁愿将它用于decorator为什么我会用装饰者的责任链?

您认为如何? CoR是否有利基用途?

+1

请添加您认为是COR任务的任务的种类,但是你装饰 – 2009-04-14 14:48:19

+0

当然解决了这个问题,我需要完成一个订单,并在某些情况下,我需要打印票据。我的装饰器解决方案是在OrderCompletionPrintDecorator中包含一个核心OrderCompleter,它应用条件逻辑和打印。和任何连锁店一样好。 – 2009-04-14 15:01:07

+0

你为什么不能只是呼吁的方法,当你想(不想),可以使用(或不)内部OrderCompleter“打印”打印?换句话说,我想知道你是否可以完全不使用任何模式来解决这个任务?在我看来,这似乎不是一个复杂的任务,需要引入抽象和复杂性。或者你所说的只是问题的简化版本。 – 2012-05-26 21:26:09

回答

53

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

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

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

如果在该示例中使用了装饰器模式,您将会收到WM_MOUSEMOVE消息的通知,但您无法阻止其他钩子处理该消息。

使用命令链模式的另一个地方是在游戏引擎中。再次,您可以挂钩引擎功能,事件和其他事情。在游戏引擎的情况下,你不想简单地添加功能。您想添加功能并阻止游戏引擎执行其默认操作。

7

我想说,一个责任链修饰器的特定形式。

+0

单行解释一切 – HakunaMatata 2016-07-28 18:41:33

4

嗯,我能想到的2种情况:

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

现在想不到更多的东西了,很想听到更多的这个话题。

13

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

VS

装饰

附加其他责任 对象动态。装饰器 为 子类提供了灵活的替代方法,用于扩展 功能。

我想大约在事情发生的顺序的。如果你把它们连起来,就会沿着链条被调用。有了装饰者,你不能保证这个订单,只能附加额外的责任。当你想将功能添加到一个对象

+0

您可以按不同的顺序附加,不可以? – 2009-04-14 14:53:58

+0

如果我们从社会的消费你是绝对正确的,如果我们从然而类设计的POV说话的POV说话,你肯定能保证这一点不亚于链可能。 – 2009-04-14 14:58:39

6

装饰使用。

COR时使用很多的演员之一可能采取的对象上采取行动。

A 特别修饰者被调用来根据类型采取行动;而COR则通过定义的链传递对象,直到其中一个角色决定动作完成。

当有升级到不同处理器的多层次COR可能被用来 - 例如,呼叫中心,客户对公司的价值判断呼叫去支持一个特定的水平。

14

这些模式之间的区别并不涉及何时或如何链可以被打破(假设链)或执行额外的行为时。它们之间的关系在于它们都使用组合来支持继承以提供更灵活的解决方案。

关键区别在于装饰者添加了新的行为,实际上拓宽了原始界面。它与普通扩展可以添加方法的方式类似,除了“子类”仅通过引用耦合,这意味着可以使用任何“超类”。

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 ...或其他。

希望这是相当清楚!

约翰

1

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

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

如果装饰器中的任何元素断链,那么将会是错误装饰器的实现,因为基础部分的行为将会丢失。当基本行为保持不变时,装饰者的想法是透明地添加新行为。

0

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

1
  1. 关键字'扩展' - 静态扩展。
  2. 修饰器模式 - 动态扩展。
  3. 责任链模式 - 只处理一个命令对象,其中一组处理对象和那些对象彼此不认识。
0

在阅读了四人帮的定义之后,我不相信有真正的区别。 (包括为方便起见)

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

维基百科将它们稍微分割出来,但其中一些有点随意。

  • 装饰通常被实现为链表。但我认为这太低级,不能被视为模式的“一部分”。
  • 责任链接链接仅处理数据,如果这是他们的责任;但确定责任和数据处理都是行为的一部分。装饰者可以轻松地做到这一点。
  • 装饰者需要你打电话给代表。
  • “纯”的CoR链接应该只调用委托,如果它不处理数据。

前两个属性没有真正区分模式。后两种做法,但Decorator和CoR通常实现的方式不强制执行这些属性 - 设计者只希望没有人写一个破坏链的装饰器或处理数据后延续链的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的,如果你想要的是开脱responsibiity的自己以防其他人搞砸你的设计 - 但为什么要这样做呢?)

2

修饰器

  1. Decorator图案允许动态地添加到单个对象的行为。

  2. 它提供了一个灵活的替代子分类扩展功能。尽管它使用继承,但它继承了最低公用分母(LCD)接口。用于装饰

    UML diagram for Decorator

    后果

UML图:

  1. 随着装饰,也可以动态地除去添加的功能。
  2. 装饰在运行时为对象添加功能,这会使调试系统功能更难。

相关链接:

When to Use the Decorator Pattern?

Decorator_pattern从维基百科

decorator从sourcemaking

链责任:

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

UML图

enter image description here

这种模式是更有效的,当:

  1. 多于一个对象可以处理一个命令
  2. 处理程序不是预先
  3. 0123已知
  4. 处理程序应该被自动确定
  5. 它希望该请求被寻址到一组对象的不明确指定其接收机
  6. 可以处理该命令对象的组必须在动态的方式来指定

相关链接:

Chain-of-responsibility_pattern从维基百科

chain-of-responsibility-pattern从oodesign

chain_of_responsibility从sourcemaking

现实世界的例子:在公司指定的角色有特别的限制,以处理购买请求。如果具有指定角色的人没有足够的权力批准购买账单,他将把命令/请求转发给他的更有权力的继任者。这条链将继续,直到命令被处理。