策略模式的原则:把继承改为组合
问题背景
假设你们公司要开发一个Duck应用,Duck分为两种,CityDuck和WildDuck,他们都能Display()和Quack()。于是你想到了类的继承。
初代完成了。这时候又有新需求。
需求一:添加Fly行为。
很简单,又用继承。
需求二:添加更多的Duck(如RubberDuck等)
当你尝试用继承的时候,Bug产生了,因为RubberDuck是不能Fly的。
于是你产生了两个想法。
想法一:
于是你想到了把RubberDuck的Fly方法override一遍
想法二:
你想到interface,于是你把能飞的鸭子实现接口flyable。
但当你添加更多Duck的时候,你发现维护起来并不容易,因为每个Duck你都要实现一遍。
最终,你想到了:
把继承变为组合,面向接口编程而不是面向实现编程。
问题解决
鸭子飞是一种行为,我们定义为接口FlyBehaviour,其中有方法Fly.
然后鸭子飞这种行为有两种实现,一种为FlyWithWings,另一种为FlyWithNoWings,我们把他们称为算法。
于是我们只需要给能飞的鸭子封装FlyWithWings的算法,不能飞的鸭子封装FlyWithNoWings的算法,这样咋爱我们调用的时候就可以直接调用FlyBeHaviour.Fly()了.
这就是策略模式
策略模式
定义:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
何时使用:一个系统有许多许多类,而区分它们的只是他们直接的行为。
如何解决:将这些算法封装成一个一个的类,任意地替换。
关键代码:实现同一个接口。
应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。 3、JAVA AWT 中的 LayoutManager。
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
板子
using System;
namespace StrategePattern
{
//抽象算法类
abstract class Strategy
{
//抽象算法方法
public abstract void AlgorithmInterface();
}
class ConcreteStrategyA : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("算法A实现");
}
}
class ConcreteStrategyB : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("算法B实现");
}
}
class ConcreteStrategyC : Strategy
{
public override void AlgorithmInterface()
{
Console.WriteLine("算法C实现");
}
}
class Context
{
Strategy m_strategy;
//封装算法
public Context(Strategy theStrategy)
{
m_strategy = theStrategy;
}
public void ContextInterface()
{
m_strategy.AlgorithmInterface();
}
}
class Program
{
static void Main(string[] args)
{
Context context;
context = new Context(new ConcreteStrategyA());
context.ContextInterface();
context = new Context(new ConcreteStrategyB());
context.ContextInterface();
context = new Context(new ConcreteStrategyC());
context.ContextInterface();
}
}
}
游戏实例——多阵营攻击流程
图片来自《设计模式与游戏完美开发》