我正在阅读java中的策略设计模式。问题设置如下
你有一个鸭子类和几种类型的鸭子。你必须编写鸭子的飞行和嘎嘎行为。你显然无法在每个鸭类方法中编写飞行,非飞行行为的代码,特别是如果你有100种不同类型的鸭子。因此,您创建了一个名为FlyingBehavior
和QuackingBehavior
的行为界面,并具有NonFlyingBehavior
或FlyWithWingsBehavior
或MuteQuackBehavior
或SqueakQuackBehavior
等实现。然后在不同类别的鸭子中的字段中设置它们。这样你就可以将行为与鸭子联系起来。
我不明白为什么必须用作文来完成,为什么不用继承。为什么不能创建子类lke NonFlyingDuck
,FlyWithWingsDuck
或SqueakingDuck
,MuteQuackingDuck
等等,然后实现方法fly()
或{{ 1}}然后为鸭子分配适当的行为。这是因为不支持多重继承。所以,如果你有一只非飞行的,吱吱作响的鸭子,那么你不能同时延伸quack()
和squeakingDuck
,或者是其他东西。有继承的方法吗?
我感到有点困惑。座右铭是'赞成合成而不是继承' 。为什么呢?
有人可以深入解释这个吗?
答案 0 :(得分:0)
我不知道深入解释,但为什么在这种情况下不使用继承很容易。因为Java不支持多重继承 想象一下,在创建了4个类(NonFlyingDuck FlyWithWingsDuck或SqueakingDuck,MuteQuackingDuck)之后,您需要添加另一个行为吗? (就像我不知道,CodingDuck)。那么你将以8个课程结束,每个CodingDuckBehavior都有2个课程(有些人知道怎么做,有些人不知道)。但为何停在这里?您可能有多个每种行为的实现,这使得继承变得不可行 如果你可以把手放在Head First Design Patterns上,我发现他们的策略模式示例非常好(并且它给出了继承路径可能出错的例子)。
答案 1 :(得分:0)
already discussed at length有很多原因。
没有多重继承通常是其中之一但与其他方面相比毫无意义我强调保留封装:当你扩展一个类时,你正在打破封装,你冒着修改它的基本行为的风险会破坏{{3 }}。
所以,正常情况下,作文比继承更受欢迎,如果你有疑问,你会通常更好地合成而不是延伸。
Liskov substitution principle你还有另一个很好的例子,总结了一些原因。
答案 2 :(得分:0)
如果你尝试继承,你最终会得到太多类型的鸭子,结构很笨拙。你怎么定义一只嘎嘎叫,哨声和只在海上飞行的鸭子以及另一种吹口哨,不嘎嘎叫,飞越陆地等的类型等等。
客户想要的是能够创建一个鸭子,然后通过调用方法来定义它的特征。
Duck mallard = new Duck();
mallard.setQuacks(true);
Duck teal = new Duck();
teal.setQuacks(true);
teal.setWhistles(true);
然后,他们可以动态地从输入数据构建这些对象,而不必事先将它们全部编码。
显然,如果愿意,可以通过子类化来优化Duck
。然后,您可以使用工厂来构建它们:
class SeaDuck extends Duck {
}
策略模式的本质是您将策略构建到代码中。
public call () {
// Encode the Strategy.
if ( quacks ) {
// Quack.
}
if ( whistles ) {
// Whistle.
}
}