设计模式(22) 策略模式

在策略模式中,一个类的行为或算法可以在运行时动态更改。

GOF对策略模式的描述为:
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients.
— Design Patterns : Elements of Reusable Object-Oriented Software

UML类图如下:

策略模式包含三个角色:

  • Context上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化。
  • Strategy抽象策略角色,策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性。
  • ConcreteStrategy具体策略角色,实现抽象策略中的操作,该类含有具体的算法。

代码示例:
以电商会员折扣为例,不同级别的会员享受的折扣是不同的,这种差异可以用策略模式来封装。

public interface Strategy
{
    double CalcPrice(double originalPrice);
}

public class PrimaryStrategy : Strategy
{
    public double CalcPrice(double originalPrice)
    {
        return originalPrice;
    }
}

public class IntermediateStrategy : Strategy
{
    public double CalcPrice(double originalPrice)
    {
        return originalPrice * 0.9;
    }
}
public class AdvancedStrategy : Strategy
{
    public double CalcPrice(double originalPrice)
    {
        return originalPrice * 0.8;
    }
}

public class PriceContext
{
    public Strategy Strategy { get; set; }

    public double GetPrice(double originalPrice)
    {
        return this.Strategy.CalcPrice(originalPrice);
    }
}

调用端:

public class Test
{
    public static void Entry()
    {
        Strategy strategy = new PrimaryStrategy();
        PriceContext price = new PriceContext();
        price.Strategy = strategy;

        Console.WriteLine(price.GetPrice(100)); //100

        strategy = new IntermediateStrategy();
        price.Strategy = strategy;
        Console.WriteLine(price.GetPrice(100)); //90

        strategy = new AdvancedStrategy();
        price.Strategy = strategy;
        Console.WriteLine(price.GetPrice(100)); //80
    }
}

示例中有若干具体的策略类,以及一个context对象,context对象会随着策略对象的改变而变更其执行算法。

策略模式的优点

  • 算法可以自由切换,只要实现抽象策略,它就成为策略家族的一个成员,通过封装角色对其进行封装,保证对外提供“可自由切换”的策略。
  • 避免使用多重条件判断,多重条件语句不易维护,而且出错的概率较大。使用策略模式后,可以由其他模块决定采用何种策略,策略家族对外提供的访问接口就是封装类,简化了操作,同时避免了条件语句判断。
  • 扩展性良好,在现有的系统中增加一个策略非常容易,只要实现接口就可以了。

策略模式的缺点

  • 策略类数量增多,每一个策略都是一个类,复用的可能性很小,类数量增多。
  • 所有的策略类都需要对外暴露,上层模块必须知道有哪些策略,并了解这些策略之间的区别,然后才能决定使用哪一个策略,这与迪米特法则是相违背的。

策略模式的适用场景

  • 多个类只有在算法或行为上稍有不同的场景。
  • 算法需要自由切换的场景。
(0)

相关推荐

  • 设计模式之策略模式

    策略模式 Strategy Intro 策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的 Context. 策略模式是一种定 ...

  • PHP设计模式之策略模式

    PHP设计模式之策略模式 策略模式,又称为政策模式,属于行为型的设计模式. Gof类图及解释 GoF定义:定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换.本模式使得算法可独立于使用它的 ...

  • 2.7万 Star!最全面的 Python 设计模式集合

    [导语]:设计模式是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易地被他人理解.保证代码可靠性.python-patterns 则是使用 ...

  • [PHP小课堂]PHP设计模式之策略模式

    [PHP小课堂]PHP设计模式之策略模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 设计模式:策略模式,Java集合定制排序的核心思想

    前言 前阵子面试的时候,有个面试官问我了解哪些设计模式吗?我说了策略模式.接着他问有哪些场景应用,我又回答他jdk的集合工具类有个排序方法就用到了策略模式,也就是java.util包下的Collect ...

  • 设计模式之策略模式和状态模式(strategy pattern & state pattern)

    本文来讲解一下两个结构比较相似的行为设计模式:策略模式和状态模式.两者单独的理解和学习都是比较直观简单的,但是实际使用的时候却并不好实践,算是易学难用的设计模式吧.这也是把两者放在一起介绍的原因,经过 ...

  • JAVA设计模式之策略模式 - Strategy

    在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改.这种类型的设计模式属于行为型模式. 在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 ...

  • 设计模式之策略模式和状态模式

    设计模式之策略模式和状态模式

  • 设计模式——策略模式

    什么是策略模式?策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化.举个例子? ...

  • PHP设计模式—策略模式

    定义: 策略模式(Strategy):它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 结构: Strategy(策略类):定义所有支持的算法的公 ...