我正在阅读关于java中的策略设计模式的文章。该问题设置如下:
你有鸭类和几种鸭子。你必须在鸭子的飞行和鸣叫行为中编码。显然,在每种鸭子类方法中,您都不能对飞行、非飞行行为进行编码,特别是如果您有100种不同类型的鸭子。因此,您创建了一个名为FlyingBehavior和QuackingBehavior的行为接口,并具有像NonFlyingBehavior或FlyWithWingsBehavior、MuteQuackBehavior或SqueakQuackBehavior这样的实现。然后将这些设置在不同类别的鸭子的字段中。这样你就能把行为和鸭子联系起来。
我不明白的是,为什么要用作文来完成,为什么不能继承。为什么不能创建子类,比如NonFlyingDuck、FlyWithWingsDuck或SqueakingDuck、MuteQuackingDuck等等,然后实现方法fly()或quack(),然后给鸭子分配适当的行为。这是因为不支持多重继承。因此,如果您有一只不会飞的、吱吱作响的鸭子,那么您就不能同时扩展squeakingDuck和NonFlyingDuck,或者是其他什么东西。有什么办法可以通过继承做到这一点吗?
我觉得有点困惑。座右铭是“喜欢构图而不是继承”。但是为什么呢?
有人能深入解释一下吗?
发布于 2014-04-02 16:06:02
我不知道深入的解释,但为什么不使用继承在这种情况下是容易的。因为Java不支持多重继承。
假设在创建了4个类(NonFlyingDuck、FlyWithWingsDuck或SqueakingDuck、MuteQuackingDuck)之后,需要添加另一个行为?(就像我不知道,CodingDuck)。好的,您将以8个类结束,每个CodingDuckBehavior有2个类(有些鸭子知道如何做,其他人不知道)。但为什么停在这里?您可能有每个行为的多个实现,这使得继承变得不可行。
如果您可以将您的手放在头第一设计模式上,我发现他们的策略模式示例非常好(它给出了继承路径可能出错的例子)。
发布于 2014-04-02 16:13:08
有许多原因,如已经详细讨论过了。
不具有多重继承通常是其中之一,但与其他继承相比没有意义,其中我强调的是保持封装:当您扩展一个类时,您将破坏封装,并且您可能会修改它的基本行为,从而破坏Liskov代换原理。
因此,通常情况下,组合比继承更好,而且作为经验规则,如果您怀疑通常会更好地编写而不是扩展。
这里还有另一个很好的例子,总结了一些原因。
发布于 2014-04-02 16:21:27
如果你尝试继承,你最终会得到太多类型的鸭子,结构不灵活。你会如何定义一只鸭子,它既鸣叫又吹口哨,只在海上飞行,还有另一种鸭子,它会吹口哨,不会嘎嘎叫,不会在陆地上飞等等。
客户想要的是能够创建一个鸭子,然后通过调用方法来定义它的特性。
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.
}
}https://stackoverflow.com/questions/22816843
复制相似问题