策略模式(Strategy Pattern)是使用一些独立的类来各自封装一些通用的算法,这些封装类都继承自同一个接口,该接口定义了算法。对于调用类来说,它只保存一个算法接口的对象,而这个对象所指代的特定算法则可以在运行时动态更改。
例如有我们有一个项目需要描述鸭子,可能有 50 种不同的鸭子都派生自基类 Duck
,鸭子一共有三种飞行方式。这时候我们如果将某一种特定的飞行方式写在基类中,则不是使用这个飞行方式的所有派生鸭子都需要对该方法重写。如果我们不在基类中定义,而在各个派生类中实现,则可能多个有相同飞行方式的鸭子派生类都有相同的代码定义飞行方式,这造成了代码冗余。
所以我们可以使用策略模式,将三种飞行方式都派生自接口 FlyBehavior
,并在鸭子基类中定义变量FlyBehavior
,然后在派生类中选择各自需要的飞行方式即可。
代码示例
算法接口及实现类
飞行方法接口1 2 3 4
| public interface IFlyBehavior { void Fly(); }
|
飞行方法实现1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class FlyNoWay : IFlyBehavior { public void Fly() { Console.WriteLine("Can not fly"); } }
public class FlyWithRocket : IFlyBehavior { public void Fly() { Console.WriteLine("Fly with rocket"); } } public class FlyWithWings : IFlyBehavior { public void Fly() { Console.WriteLine("Fly with wings"); } }
|
环境类
鸭子基类1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public abstract class Duck { private IFlyBehavior flyBehavior;
public Duck() { }
public abstract void disPlay();
public void PerformFly() { flyBehavior.Fly(); }
public void setFlyBehavior(IFlyBehavior fb) { flyBehavior = fb; } }
|
鸭子派生类1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class BlackDuck : Duck { public BlackDuck() : base() { setFlyBehavior(new FlyWithWings()); }
public override void disPlay() { Console.WriteLine("I am a black duck"); } } public class RubberDuck : Duck { public RubberDuck() : base() { setFlyBehavior(new FlyNoWay()); }
public override void disPlay() { Console.WriteLine("I am a rubber duck"); } }
|
测试及结果
测试代码1 2 3 4 5 6 7 8 9
| RubberDuck rubberDuck = new RubberDuck(); rubberDuck.disPlay(); rubberDuck.PerformFly();
BlackDuck blackDuck = new BlackDuck(); blackDuck.disPlay(); blackDuck.PerformFly(); blackDuck.setFlyBehavior(new FlyWithRocket()); blackDuck.PerformFly();
|
运行结果