Java 战略模式的实例

Java 战略模式的实例,java,design-patterns,inheritance,Java,Design Patterns,Inheritance,我在读java中的策略设计模式。问题设置如下 你有一个鸭子班和几种鸭子。你必须对鸭子的飞行和嘎嘎声进行编码。显然,您不能在每个duck类方法中编写飞行、非飞行行为的代码,特别是如果您有100种不同的duck。因此,您创建了一个名为FlyingBehavior和quackbehavior的行为接口,并具有类似NonFlyingBehavior或flyingsbehavior或MuteQuackBehavior或squekquackbehavior>的实现。然后将这些设置在不同鸭子类别的字段中。这样

我在读java中的策略设计模式。问题设置如下

你有一个鸭子班和几种鸭子。你必须对鸭子的飞行和嘎嘎声进行编码。显然,您不能在每个duck类方法中编写飞行、非飞行行为的代码,特别是如果您有100种不同的duck。因此,您创建了一个名为
FlyingBehavior
quackbehavior
的行为接口,并具有类似
NonFlyingBehavior
flyingsbehavior
MuteQuackBehavior
squekquackbehavior>的实现。然后将这些设置在不同鸭子类别的字段中。这样你就会把这些行为和鸭子联系起来

我不明白的是,为什么必须用构图,为什么不能用继承。为什么不能创建子类lke
NonFlyingDuck
FlyWithWingsDuck
SqueakingDuck
mutequackduck
等等,然后实现方法
fly()
quack()
,然后为鸭子分配适当的行为。这是因为不支持多重继承。所以,如果你有一只不会飞的吱吱叫的鸭子,那么你不能同时扩展
squeakingDuck
NonFlyingDuck
,或者它是其他东西。有什么方法可以通过继承来实现这一点吗

我觉得有点困惑。格言是“重组合轻继承”。为什么呢


有人能详细解释一下吗?

我不知道有什么详细的解释,但是为什么在这种情况下不使用继承是很容易的。因为Java不支持多重继承。
想象一下,在创建了4个类(带Wingsduck的非飞行鸭或SqueakingDuck、MuteQuackingDuck)之后,您需要添加另一个行为?(就像我不知道一样,CodingDuck)。好的,你将以8节课结束,每节课2节用于你的CodingDuckBehavior(有些鸭子知道怎么做,有些鸭子不知道怎么做)。但是为什么停在这里?每个行为可能有多个实现,这使得继承变得不可行。

如果你能动手的话,我发现他们的策略模式示例考虑得很好(它给出了在继承路径上可能出现错误的示例)。

原因有很多,如下所示

没有多重继承通常是其中之一,但与其他继承相比毫无意义,其中我要强调的是保留封装:当您扩展一个类时,您破坏了封装,并且您有可能修改它的基本行为,从而破坏封装

因此,通常情况下,组合优先于继承,根据经验法则,如果您有疑问,通常情况下,组合比扩展更好


还有一个很好的例子总结了其中的一些原因。

如果您尝试使用继承,您将得到太多类型的Duck,其结构非常笨拙。你如何定义一只鸭子,它会嘎嘎地叫,只会在海面上飞,还有另一种鸭子会吹口哨,不会嘎嘎地叫,只会在陆地上飞等等

客户想要的是能够创建一个duck,然后通过调用方法定义它的特性

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.
  }
}

这是头先设计模式吗?因为他们有一个类似的例子和所有的原因,首选的解决方案。当我找到它时会把它放在这里我想说。。。你读了整本书吗?他们在头先设计模式中解释得很好。这是头先设计模式。问题显然是多重继承。谢谢大家的帮助。在支持多重继承的语言中,继承是很容易做到的,但是在像Java这样只得到一个超类的语言中,你必须开始对类的层次结构顺序做出一些任意的决定。无论如何,你应该避免多重继承-太好了。所以问题是多重继承。想想看,是的,如果你对为什么没有多重继承感兴趣,谷歌“java钻石问题”,看看接口为什么存在:)