策略模式

策略模式

定义(来自维基百科)

策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。比如每个人都要交“个人所得税”,但是“在美国交个人所得税”和“在中国交个人所得税”就有不同的算税方法。

特征

  • 定义了一族算法(业务规则);
  • 封装了每个算法;
  • 该族的算法可以互相替换。

Alt Text

示例

// 计算奖金接口
interface ISalary
{
    void Calc();
}

public class Level1Salary:ISalary
{
    public static readonly int Level = 1;

    public void Calc()
    {
        Console.WriteLine("等级1的奖金计算");
    }
}

public class Level2Salary:ISalary
{
    public static readonly int Level = 2;

    public void Calc()
    {
        Console.WriteLine("等级2的奖金计算");
    }
}

public class Level3Salary:ISalary
{
    public static readonly int Level = 3;

    public void Calc()
    {
        Console.WriteLine("等级3的奖金计算");
    }
}

public Context
{
    ISalary salaryStragegy;

    public Context(ISalary salary)
    {
        this.salaryStragegy = salary;
    }

    public void Calc()
    {
        this.salaryStragegy.Calc();
    }
}

// 消费场景
public class MainApp
{
    public static void Main()
    {
        Context context;

        context = new Context(new Level1Salary());
        context.Calc();

        context = new Context(new Level2Salary());
        context.Calc();

        context = new Context(new Level3Salary());
        context.Calc();

        // 
        foreach (var item in new List<int> {1, 2, 3})
        {
            CalcSalary(item);
        }
    }

    // 稍微改进一下
    public List<ISalary> LevelSalarys = new List<ISalary>{new Level1Salary(), new Level2Salary(), new Level3Salary()};

    public void CalcSalary(int level)
    {
        var levelSalary = LevelSalarys.Find(l=>l.Level.equals(level));
        new Context(levelSalary).Calc();
    }
}

思考:如何通过MEF的方式对策略模式进行消费?

解决的问题

客户端(调用者)可以根据条件来选择不同的策略来解决不同的问题。

优点

  1. 由于策略类实现自同一个接口,策略类可以自由切换;
  2. 易于扩展,符合开闭原则(面向修改封闭,面向扩展开放),基本上可以在不改变原有代码的基础上进行扩展。

缺点

  1. 随着策略类的数量逐渐增多,维护各个策略类会给开发带来额外的开销;
  2. 必须对客户端暴露所有的策略类,因为使用哪种策略是由客户端决定的

适用的场景

  1. 几个类的主要逻辑相同,只在部分逻辑的算法和行为上稍有区别的情况。
  2. 有几种相似的行为,或者说算法,客户端需要动态地决定使用哪一种,那么可以使用策略模式,将这些算法封装起来供客户端调用。

总结

策略模式是一种简单常用的模式,我们在进行开发的时候,会经常有意无意地使用它,一般来说,策略模式不会单独使用,跟模版方法模式、工厂模式等混合使用的情况比较多。

本文完。

posted @ 2017-08-14 09:17  DebugLife  阅读(297)  评论(0编辑  收藏  举报