Java 违反利斯科夫'的战略模式;s替代原理
我正在实施策略模式,以实施不同类型鸭子的行为。代码如下:Java 违反利斯科夫'的战略模式;s替代原理,java,c#,.net,design-patterns,Java,C#,.net,Design Patterns,我正在实施策略模式,以实施不同类型鸭子的行为。代码如下: public interface IFlybehaviour { public void fly(); } public class GeneralFlybehaviour { public void fly() { Console.WriteLine("I can fly as a duck"); } } public abstract class Duck { IFlybehaviour flybeha
public interface IFlybehaviour
{
public void fly();
}
public class GeneralFlybehaviour
{
public void fly()
{
Console.WriteLine("I can fly as a duck");
}
}
public abstract class Duck
{
IFlybehaviour flybehaviour;
Duck()
{
}
public void PerformFly()
{
flybehaviour.fly();
}
}
public class SimpleDuck : Duck
{
public SimpleDuck(IFlybehaviour flybehaviour)
{
flybehaviour = new GeneralFlybehaviour();
}
}
In the main method
void main()
{
Duck d = new SimpleDuck();
d.PerformFly();
}
这同时遵循了“开闭原则””和“Liskov的替代原则”,在这两个原则下,我可以创建50种不同类型的鸭子,如SimpleDuck
,FlyingDuck
等
现在我需要一门课,它有一种特殊的力量来满足门徒的愿望,比如说:
//public class ComplicatedDuck extends Duck (Java)
public class ComplicatedDuck : Duck
{
public ComplicatedDuck(IFlybehaviour flybehaviour)
{
flybehaviour = new GeneralFlybehaviour();
}
public void GrantWishes()
{
Console.WriteLine("Wish Granted")
}
}
有了这个变化,我们知道它违反了“Liskov的替换原则”,在这个原则中,这个子类不会完全替换它的基类
假设我在“抽象类Duck”中再添加一个函数,那么所有继承的成员至少需要提供一个表示“我不满足特殊愿望”的实现
在这个场景中,哪一个是更好的解决方案,在复杂的DDUCK类中添加一个方法还是扩展基类
注意:同样的概念也适用于Java,只是将“:”替换为
“implements”关键字
我想你错过了从Duck类继承Duck的机会。它必须像- 鸭子
- 您可以将现有方法public void GrantWishes()移动到抽象类Duck
- 使用空定义将其设置为虚拟
- 在复杂的DDuck类中,根据需要重写行为
- 在SimpleDuck类中不执行任何操作
带回家的部分。在不需要它们的派生类上强制使用方法是很麻烦的。然而,在可行的情况下使一切都可组合也是一种浪费。您只需在逻辑上划清界限策略模式是为
IFlyBehavior
提供不同的实现,而不是为Duck
提供继承类
代码的一个问题是,Duck
基类中有一个从未使用过的私有字段。它只能由Duck使用,因此所有继承类型都无法访问它。如果PerformFly()
您将得到一个NullReferenceException-always。如果要继承Duck
,可能需要在Duck的构造函数中使用IFlyBehavior
也
有点违背了拥有战略模式的目的,因为它强制特定的实施。我想如果你想使用一个特定的
IFlyBehavior
实现,而不是从Duck继承,你会使用composition,这可能是错误的,但是composedduck
(如果它是一个抽象Duck
的派生类,并且有一个方法,你没有添加)这似乎并不违反LSP,因为它可以像任何其他鸭子一样飞行,您可以通过引用基类来使用它。谢谢。我还建议您对代码进行重新排序。从基接口和类开始。人类从上到下阅读文本(至少在英语文本的上下文中)。因此,不要使用以后定义的名称。@KozhevnikovDmitry:整个问题很复杂,Duck有GrantWishes(),它不存在于基类Duck中,甚至在其他50个派生类中,如SimpleDuck等。public SimpleDuck(IFlybehaviour FlyBehavior){FlyBehavior=new GeneralFlyBehavior();}
-传递参数,分配给它其他的东西,不要在任何地方使用它。这没有道理。你想做什么?@user1400915,对,但是它没有违反LSP。至少在您提供的上下文中。将GrantWiches
添加到基类不是一个好主意。这似乎违反了SRP。最好看一看桥接模式,一种类似于IWishGranter的工具。只是澄清一下,如果一辆汽车已经实现了IRadio,这是一种组合,它是否仍然被认为遵守“Liskov原则”?在我的理解中,派生类的属性或方法必须是完全可替换的,因为子类从不破坏父类类型定义,并且子类型可以替换它们的基类型。
flybehaviour = new GeneralFlybehaviour();