前置文章: 用心理解设计模式——设计模式的原则
设计模式相关代码已统一放至 我的 Github
一、定义
行为型模式之一。
Define a family of algorithms, encapsulate each one, and make them interchangeable.
(定义一组算法,将每个算法都封装起来,并使它们之间可以互换。)
二、结构解析
策略模式的一般结构有三种角色: 抽象策略、具体策略、环境/上下文。
抽象策略,为将要封装的算法提供一个公共接口方法。
具体策略,实现抽象策略定义的接口方法。
环境/上下文,持有具体策略,并可灵活切换;对外,为高层模块提供一个接口方法。
三、评价
策略模式,作为行为型模式之一,它将 “策略” 这个抽象概念抽象为类,并定义了为满足不同需求对 “策略” 进行切换的行为过程。让策略算法得以从客户逻辑中剥离出来,减轻客户类负担,降低程序复杂度。
策略模式符合开闭原则(避免了条件分支语句的出现,通过派生新类使策略易扩展)。
策略模式中的 “环境/上下文类” 是策略模式的重点。该类对具体策略进行了封装和额外的处理(用策略算法实现为高层模块提供的对外接口),避免了客户类对策略类的直接调用,符合迪米特法则(让客户只用关心自己要做的,不用关心怎么组织算法达成目标)。
四、实现
using UnityEngine;
namespace Strategy
{
//抽象策略
public abstract class Strategy
{
public abstract void AlgorithmInterface();
}
//具体策略A,实现A算法
public class ConcretesStrategyA : Strategy
{
public override void AlgorithmInterface()
{
Debug.Log("算法A");
}
}
//具体策略A,实现B算法
public class ConcretesStrategyB : Strategy
{
public override void AlgorithmInterface()
{
Debug.Log("算法B");
}
}
//环境/上下文,持有具体策略,并可灵活切换;对外,为高层模块提供一个接口方法,方法中对策略进行封装或额外的组织,避免高层模块对策略的直接调用。
public class Context
{
Strategy strategy;
public Context(Strategy strategy)
{
this.strategy = strategy;
}
public void DoSth()
{
//额外的预先操作
this.Before();
//最终调用真实主题的业务方法
this.strategy.AlgorithmInterface();
//额外的后续操作
this.After();
}
private void Before() { }
private void After() { }
}
//客户
public class Client
{
static public void Main()
{
Context contextA = new Context(new ConcretesStrategyA());
Context contextB = new Context(new ConcretesStrategyB());
contextA.DoSth();
contextB.DoSth();
}
}
}