用心理解设计模式——策略模式 (Strategy Pattern)

前置文章: 用心理解设计模式——设计模式的原则 

设计模式相关代码已统一放至 我的 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();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/NRatel/article/details/84257027
今日推荐