首先需要说明的是该系列的所有内容都是基于headfirst设计模式来描述的。因为我之前也看过不少关于设计模式的书,还是发现这本最好,因为这本书里面给出的例子是最贴切实际的。不说了,开始这个系列吧!
策略模式
设计原则①:找出应用中可能需要变化的地方,把他们独立出来,不要和那些不变的代码混合在一起。把会变化的部分提取出来,以便以后能够轻易的对这部分进行扩充或改动,而不会影响到不变的那部分代码。这样,代码变化引起的不经意后果变少,系统变得更有弹性。
设计原则②:针对接口编程,而不是针对实现进行编程。从现在开始,变化的部分被抽象到接口中,这样,鸭子就不用知道行为的具体实现了。
设计原则③:多用组合,少用继承。
策略模式定义:定义了算法族,分别封装起来,让他们之间可以互相替换。此模式让算法的变化独立于使用算法的客户。
背景:joe设计了一个鸭子游戏,这里面所有的鸭子都有一个基类,所有的鸭子都从这个基类来继承一致的行为,但是这样的设计忽略了一个重要的因素:变化。不是所有的子类都具有相似的行为,那这个世界也就不再精彩了。
下面是针对这个模式对鸭子游戏进行的设计:
public abstract class Duck { public string Color { get; set; } public string Name { get; set; }//假设鸭子有一个名字 private IQuackable _quackable; private IFlyable _flyable; protected Duck(IQuackable quack,IFlyable fly) { _quackable = quack; _flyable = fly; } public override string ToString() { return $"my name is {Name},i am {Color}"; } public virtual void Swim() { Console.WriteLine("all duck can swim"); } } public interface IQuackable { void Quack(); } public interface IFlyable { void Fly(); } public class ICanQuack : IQuackable { public void Quack() { Console.WriteLine("i can quack"); } } public class ICanFly:IFlyable { public void Fly() { Console.WriteLine("i can fly"); } }
首先对鸭子设计了一个基类,这个基类是一个抽象类,所有其他的鸭子都会从这里继承。重要的是对鸭子的叫和飞这两种行为进行了抽离,做成了接口,因为不是所有的鸭子都会飞,也不是所有的鸭子都会叫。这样,我们在定义一个鸭子子类的时候,可以针对这种鸭子的特性进行编程。也就提高了系统的弹性。其中,将鸭子的一些行为独立出来这个符合上面提到的设计原则①,Duck类中针对的是两个接口来获取具体的行为这个符合设计原则②,将那两个接口作为Duck的字段符合设计原则③。