Skip to content

Head First 设计模式 01-策略模式

🏷️ 《Head First 设计模式》

策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,次模式让算法的变化独立于使用算法的客户。

如下类图所示,将 Duck 类的行为抽象为 Behavior 接口,然后在其子类 MallardDuck 中对 Behavior 属性指定其具体实现。

此种方式还有优点就是 Behavior 属性可以在运行时动态的改变,使系统的弹性更大。

设计原则

No.1

找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

No.2

针对接口封装,而不是针对实现编程。

No.3

多用组合,少用继承。

示例代码

Duck

csharp
namespace StrategyPattern
{
    public abstract class Duck
    {
        public FlyBehavior FlyBehavior { get; set; }
        public QuackBehavior QuackBehavior { get; set; }

        public Duck()
        {

        }

        public void performFly()
        {
            FlyBehavior.Fly();
        }

        public void performQuack()
        {
            QuackBehavior.Quack();
        }

        public void Swim()
        {
            Console.WriteLine("All ducks float, even decoys!");
        }
    }
}

FlyBehavior

csharp
namespace StrategyPattern
{
    public interface FlyBehavior
    {
        void Fly();
    }
}

FlyWithWings

csharp
namespace StrategyPattern
{
    public class FlyWithWings : FlyBehavior
    {
        public void Fly()
        {
            Console.WriteLine("I'm flying!!");
        }
    }
}

QuackBehavior

csharp
namespace StrategyPattern
{
    public interface QuackBehavior
    {
        void Quack();
    }
}

Quack

csharp
namespace StrategyPattern
{
    public class Quack : QuackBehavior
    {
        void QuackBehavior.Quack()
        {
            Console.WriteLine("Quack");
        }
    }
}

MallardDuck

csharp
namespace StrategyPattern
{
    public class MallardDuck : Duck
    {
        public MallardDuck()
        {
            QuackBehavior = new Quack();
            FlyBehavior = new FlyWithWings();
        }

        public void Display()
        {
            Console.WriteLine("I'm a real Mallard duck.");
        }
    }
}

Program

csharp
namespace StrategyPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            Duck mallard = new MallardDuck();
            mallard.performQuack(); // print Quack
            mallard.performFly(); // print I'm flying!!
            Console.ReadLine();
        }
    }
}