架构师修炼之设计模式 – 策略模式(Strategy) 【Python与C#实现】

程序员,我为你祝福

愿你有一个灿烂的前程

愿你有情人终成眷属

愿你在尘世获得幸福

我只想成为架构师,走遍江湖!

目录

  • 模式定义
  • 模式分类
  • 模式结构
  • 实例(C#与Python版)
  • 优点
  • 缺点
  • 使用场景

模式定义

它定义一系列算法,将每一个算法封装起来,并让它们之间可以相互替换。此模式让算法的变化,不会影响到使用算法的客户,也称为政策模式(Policy)。

模式分类

属于行为型模式。

模式结构

主要成员:

  • Context:上下文类。用一个具体ConcreteStrategy策略来配置,维护一个对Strategy对象的引用;
  • Strategy:抽象策略类。定义算法公共接口;
  • ConcreteStrategy:具体策略类。继承于Strategy,封装具体的算法或者行为。

实例

Python版本:


 Strategy.py

from abc import ABC, abstractmethod


class Strategy(ABC):
    """抽象类"""

    def __init__(self):
        """构造函数"""
    @abstractmethod
    def algorithmInterface(self):
        """抽象方法"""

View Code

ConcreteStrategy.py

from Strategy import Strategy

class ConcreteStrategyA(Strategy):
    def __init__(self):
        super().__init__()
    def algorithmInterface(self):
        print("算法A实现")

class ConcreteStrategyB(Strategy):
    def __init__(self):
        super().__init__()
    def algorithmInterface(self):
        print("算法B实现")

View Code

Context.py

from Strategy import Strategy


class Context():
    def __init__(self):
        """构造函数"""

    def setStrategy(self, strategy):
        """设置算法"""
        self._strategy = strategy

    def contextInterface(self):
        """执行算法"""
        self._strategy.algorithmInterface()

View Code

Client.py

from Context import Context
from ConcreteStrategy import ConcreteStrategyA, ConcreteStrategyB

context = Context()
context.setStrategy(ConcreteStrategyA())
context.contextInterface()

context.setStrategy(ConcreteStrategyB())
context.contextInterface()

View Code

执行结果:

C#版本:


Strategy.cs

using System;

namespace Strategy
{
    public abstract class Strategy
    {
        public abstract void AlgorithmInterface();
    }
}

ConcreteStrategyA.cs

using System;

namespace Strategy
{
    public class ConcreteStrategyA : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法A实现");
        }
    }
}

ConcreteStrategyB.cs

using System;

namespace Strategy
{
    public class ConcreteStrategyB : Strategy
    {
        public override void AlgorithmInterface()
        {
            Console.WriteLine("算法B实现");
        }
    }
}

Context.cs

using System;

namespace Strategy
{
    public class Context
    {
        private Strategy _strategy;
        public Context()
        { }

        public void SetStrategy(Strategy strategy)
        {
            _strategy = strategy;
        }

        public void ContextInterface()
        {
            _strategy.AlgorithmInterface();
        }
    }
}

Client.cs

using System;

namespace Strategy
{
    public class Client
    {
        public static void Main(string[] args)
        {
            var context = new Context();
            context.SetStrategy(new ConcreteStrategyA());
            context.ContextInterface();

            context.SetStrategy(new ConcreteStrategyB());
            context.ContextInterface();

            Console.Read();
        }
    }
}

优点

  • 将算法封装到一个个独立的Strategy子类,可以在使用算法时消除条件判断语句。
  • 由于每个算法是独立的,方便单元测试。
  • 由于抽象类Strategy定义了一系列算法或行为的接口,通过继承它可以灵活快速的添加新算法或行为。
  • 算法或行为的调用通过Context上下文处理,方便管理。

缺点

  • 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。

使用场景

以下情况可以使用策略模式:

  • 如果系统中某个类的某一行为存在多种实现方式,而且这些实现方式可以互换时;(比如C#的泛型)
  • 一个系统需要动态地在几种算法中选择一种时;(比如商场打折系统)
  • 如果一个对象有很多的行为,这些行为使用多重的条件选择语句时;
  • 如果需要对算法数据结构进行保密时;