装饰通过构造函数注入与简单继承

时间:2012-08-26 18:46:52

标签: design-patterns inversion-of-control

有人可以告诉我使用另一个类的构造函数注入而不是类继承来创建装饰器类之间的差异(如同的好处一样)吗?在我能想到的例子中,我可以通过两种方式之一实现相同的最终目标,但我怀疑我缺少一些基本的东西。

3 个答案:

答案 0 :(得分:4)

装饰器模式涉及组成对象。为了能够继承该对象的类型,它显然必须是可继承的。并非所有类型都是为继承而设计的,即,它们都是基类,即使它们是纯技术观点可以继承(我认为这是设计缺陷)。

装饰器模式的存在理由是能够在不修改对象本身的情况下修改对象的行为。通过继承,你实际上是在修改对象本身,然后你得到的是通过多态的定期行为改变,这意味着你没有完成同样的事情。

因此,装饰和继承都有其用途。当其中任何一个为真时使用装饰

  • 你不能继承(例如,如果C#中的类是sealed
  • 你不应该继承(该类显然不是基类)
  • 你想多次改变一个特定对象的行为(通过用不同行为的装饰器包装它)

请注意,继承是OO工具箱中最强大的工具。强大的力量带来了巨大的责任,并不总是很容易应对。我会说:总是撰写或聚合。当那不能做,继承。如果你不能继承,那就更加努力地撰写或聚合。“

答案 1 :(得分:0)

我将恢复如下:

什么时候应该继承?

当对象来自相同的语义层次结构并表示 is-a 关系时。

这意味着什么?

Cat 是-a Feline,确实是Feline 是-a Vertebrate,等等。

你应该什么时候装饰?

当对象不代表是-a 关系时。但是,是的,CoffeeMilk都可以位于同一层次结构中。但是,如果您were to sell Cappuccino,您不会说咖啡牛奶,而是用Milk装饰它。

<强>结论:

Is-a has-a 不同。一个是子类型,另一个是 组成的一部分。

但是,请看:https://stackoverflow.com/questions/1621344/head-first-design-patterns-decorator-pattern

一个真实的例子是为您的控制器或服务创建security container as a Decorator以进行ACL检查。

答案 2 :(得分:0)

装饰的另一个很好的理由是,它为您提供了装饰界面而不是类的选项。然后你变得松散耦合,并且可以在不编写更多代码的情况下将正交装饰行为添加到接口的多个实现中。