我想问一下这本书上的鸭子例子让我感到困惑,我感到矛盾。
问题
结论
他说" 当joe向鸭子超类添加新行为时,他还添加了对sume Duck子类不适合的行为"
但在结论中他添加了performFly()
和performQuack();
有什么不同,因为我认为它与he was also adding behavior that was not appropiate for sume Duck subclasses
相同?
答案 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()
代码重用如何?那么,您必须使接口尽可能严格,以确保接口中的大多数更改都将导致程序无法编译。