设计模式(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 Softwarethis

UML类图以下:
3d

策略模式包含三个角色:code

  • 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);
    }
}

调用端:blog

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对象会随着策略对象的改变而变动其执行算法。接口

策略模式的优势get

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

策略模式的缺点it

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

策略模式的适用场景电商

  • 多个类只有在算法或行为上稍有不一样的场景。
  • 算法须要自由切换的场景。
相关文章
相关标签/搜索