Duck示例策略模式 - 头部设计模式

时间:2015-01-11 13:37:51

标签: java php design-patterns

我想问一下这本书上的鸭子例子让我感到困惑,我感到矛盾。

  1. 问题 enter image description here

  2. 结论 enter image description here

  3. 他说" 当joe向鸭子超类添加新行为时,他还添加了对sume Duck子类不适合的行为"

    但在结论中他添加了performFly()performQuack();有什么不同,因为我认为它与he was also adding behavior that was not appropiate for sume Duck subclasses相同?

    **图片取自头部第一个设计图案 **这个问题并没有说明这本书不好,这本书在我看来真的很好。这只是我在问一些我从书中得不到的东西。

4 个答案:

答案 0 :(得分:4)

当您赞成合成优于继承时,策略模式有效 http://en.wikipedia.org/wiki/Composition_over_inheritance

这是一个很好的做法,因为您可以更改类的行为而无需更改任何代码。而且你也不需要一个庞大的类树。您还可以动态更改类的行为。

它在示例中的作用是在父类中定义“行为”。在父类中,您定义Duck可以具有飞行行为和嘎嘎行为。但这并不意味着孩子们必须要嘎嘎叫或飞行。

你可以拥有一只非飞鸭,当你打电话给“飞”时,它什么也不会做,因为我们会有“非飞行”行为。

您可以随时更改此鸭子的行为,而不是硬编码鸭子在课堂上的作用。

答案 1 :(得分:1)

在结论中,他正在添加两个具有fly()功能的新类。但是,该功能并不总是让鸭子飞起来。橡皮鸭不能飞,所以他们使用FlyNoWay类的实例。其他可以飞行的鸭子使用FlyWithWings类的实例。 flyBehavior类中的字段Duck可能会在构造函数中设置。

函数performFly()会调用fly()函数来选择任何类。

正如kainaw在评论中所说,这是一个相当复杂的解决方案。但是,它仍然可以使用。假设您正在创建一个鸭子设计程序。如果用户选择鸭子是否可以飞行,则不能进行硬编码。您可以创建一个布尔值,但您可能需要处理更复杂的情况,如行为。您可能需要WildDuckBehavior班级和DomesticDuckBehavior,每个班级都有自己的行动信息。基本上,本书中的示例是如何使用它的简化版本。

答案 2 :(得分:1)

我不是设计模式的大师,但在我读这本书的时候,我对这个特定章节的第一感觉就是接口的构建和实现方式,违反了一个众所周知的编程原则: the Interface Segregation Principle (ISP) 基本上这个原则说明了

  

不应该强迫任何客户端依赖它不使用的方法

因为一些不飞的鸭子实施了fly()方法,即便它们也不需要它。 也就是说,我认为在这种特殊情况下,实现所有接口方法是不可避免的,因为在客户端我们使用的是多态行为,我们需要确保即使未使用也可以使用所有方法。

答案 3 :(得分:0)

您是正确的。本书提供的解决方案存在一个巨大的问题: “ FlyNoWay”不是“ FlyBehaviour”的子情况。为了具有任何意义,FlyBehaviour必须具有飞行的能力。从其继承的类将指定行为(使用翅膀等飞行)。子类不能少于其继承的类。

仔细观察一下,“ FlyNoWay”只是一个伪类,它是为了以不适当的方式解决多态性问题而引入的。

正确的方法是使用接口。

Product.objects.filter(bundles__isnull=False).distinct()

代码重用如何?那么,您必须使接口尽可能严格,以确保接口中的大多数更改都将导致程序无法编译。