我正在实施战略模式,以实现不同类型的鸭子的行为。这是代码:
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();
}
这遵循“开放封闭原则”和“利斯科夫的替代原则”,我可以创造50种不同类型的鸭子,如SimpleDuck
,FlyingDuck
等。
现在我需要一个班级ComplicatedDuck
,它有一个特殊的权力,以授予其门徒的愿望,让我们说:
//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”中添加一个函数,那么所有继承的成员至少需要提供一个实现,说“我不授予特殊的愿望”。
在这种情况下,这是更好的解决方案,在ComplicatedDuck类中添加方法或扩展BaseClass
注意:相同的概念适用于Java,也只是用“implements”关键字替换“:”。
这是composition vs inheritance.的经典案例
你创造了一个基础车...所有你可预见的汽车都有门和轮子,以及一些描述的引擎......继承运作良好......但无线电是可选的。你是做什么。你用的是作文。
你创建了一个名为IRadio的接口,对于每个有收音机的汽车,你用IRadio装饰它(假设这是C#),这就是组合。它很容易检查汽车是否有收音机,只需检查IRadio,它可以轻松打开任何有RadioEnabled车的收音机。
带回家的部分。在不需要它们的派生类上强制方法是混乱的。然而,当它可以被衍生化时,使一切都可以合成也是一种浪费。你需要逻辑地绘制线条
策略模式是关于IFlyBehavior
的不同实现,而不是为Duck
继承类。
您的代码的一个问题是您的Duck
基类中有一个永远不会使用的私有字段。它只能由Duck使用,因此所有继承类型都无法访问它。如果你PerformFly()
你会得到一个NullReferenceException - 总是。如果你想继承Duck
,可能想要在Duck的构造函数中使用IFlyBehavior。
也
flybehaviour = new GeneralFlybehaviour();
有点破坏了战略模式的目的,因为它强制对其进行特定的实施。我想如果你想使用特定的IFlyBehavior
实现,你可以使用组合而不是继承Duck
我想你只是错过了继承Duck类的ComplicatedDuck。它必须像 - ComplicatedDuck:Duck
这样就不会违反替代原则。