策略模式(Stragety Pattern)

策略模式属于行为型模式,它定义了一系列的算法,并将每一个算法封装起来,而且使他们可以相互替换,让算法独立于使用它的客户而独立变化。

使用策略模式可以把行为和环境分割开来。环境类负责维持和查询行为类,各种算法则在具体策略类中提供。

角色:

1、抽象策略(Strategy)

这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口;

2、具体策略(Concrete Strategy)

实现抽象策略的具体策略类,包装了相关的算法或行为;

3、环境类(Context)

持有一个Strategy类的引用并可以根据逻辑选择实例相应的策略。

示例:

1.png

命名空间StragetyPattern中包含策略基类Tax以及它的8个实现类,Context环境类持有策略基类。本示例通过一个优雅的方式来计算个人所得税。

C#开发笔记之04-如何用C#优雅的计算个人所得税?

namespace StragetyPattern
public abstract class Tax {    protected decimal TaxRate = 0;    protected decimal QuickDeduction = 0;    public virtual decimal Calculate(decimal income) {        return income * TaxRate - QuickDeduction;    }}

策略基类Tax,表示个人所得税,TaxRate为税率,QuickDeduction为速算扣除数,Calculate计算相应收入的个人所得税。

public class Level0 : Tax {    public Level0() {        TaxRate = 0.00m;        QuickDeduction = 0;    }}

0级个人所得税阶梯,表示个人所得税的初始状态。

public class Level1 : Tax {    public Level1() {        TaxRate = 0.03m;        QuickDeduction = 0;    }}

1级个人所得税阶梯。

public class Level2 : Tax {    public Level2() {        TaxRate = 0.10m;        QuickDeduction = 105;    }}

2级个人所得税阶梯。

public class Level3 : Tax {    public Level3() {        TaxRate = 0.20m;        QuickDeduction = 555;    }}

3级个人所得税阶梯。

public class Level4 : Tax {    public Level4() {        TaxRate = 0.25m;        QuickDeduction = 1005;    }}

4级个人所得税阶梯。

public class Level5 : Tax {    public Level5() {        TaxRate = 0.30m;        QuickDeduction = 2755;    }}

5级个人所得税阶梯。

public class Level6 : Tax {    public Level6() {        TaxRate = 0.35m;        QuickDeduction = 5505;    }}

6级个人所得税阶梯。

public class Level7 : Tax {    public Level7() {        TaxRate = 0.45m;        QuickDeduction = 13505;    }}

7级个人所得税阶梯。

public class Context {    private Tax _tax = null;    private const decimal EXEMPTION_VALUE = 3500m;    private List<decimal> _taxLevel = new List<decimal>{        0,        1500,        4500,        9000,        35000,        55000,        80000,        decimal.MaxValue    };    private List<Type> _levels = new List<Type>();    private void GetLevels() {        _levels = AppDomain.CurrentDomain.GetAssemblies()                           .SelectMany(tp => tp.GetTypes()                           .Where(t => t.BaseType == typeof(Tax)))                           .ToList();    }    public Context() {        GetLevels();    }    public Context Calculate(decimal income) {        _tax = new Level0();        var result = income - EXEMPTION_VALUE;        for(int i = 1; i <= _taxLevel.Count - 1; i++) {            if(result > _taxLevel[i - 1] && result <= _taxLevel[i]) {                _tax = (Tax)Activator.CreateInstance(_levels[i]);            }        }        Console.WriteLine($"Income = {income}," + $"tax = {_tax.Calculate(result)}!");        return this;    }}

环境类Context,首先需要维持对Tax的引用,EXEMPTION_VALUE表示免征额(本例使用3500元),之后通过反射和一些技巧选择相应的Tax实现类来计算相应阶梯的个人所得税。

public class Program {    private static Context _context = new Context();    public static void Main(string[] args) {        _context.Calculate(2500.00m)                .Calculate(4900.00m)                .Calculate(5500.00m)                .Calculate(7000.00m)                .Calculate(10000.00m)                .Calculate(16000.00m)                .Calculate(43000.00m)                .Calculate(70000.00m)                .Calculate(100000.00m)                .Calculate(4500.00m)                .Calculate(1986.00m);        Console.ReadKey();    }}
Income = 2500.00,tax = 0.0000!Income = 4900.00,tax = 42.0000!Income = 5500.00,tax = 95.0000!Income = 7000.00,tax = 245.0000!Income = 10000.00,tax = 745.0000!Income = 16000.00,tax = 2120.0000!Income = 43000.00,tax = 9095.0000!Income = 70000.00,tax = 17770.0000!Income = 100000.00,tax = 29920.0000!Income = 4500.00,tax = 30.0000!Income = 1986.00,tax = 0.0000!

优点:

1、策略类的等级结构定义了一个算法或行为族,恰当使用继承可以把公共的代码移到父类里面,从而避免重复的代码;
2、继承可以处理多种算法或行为,可以避免使用多重条件转移语句。

缺点:

1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类;
2、策略模式造成很多的策略类,造成“子类爆炸”。

使用场景:

1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为;
2、一个系统需要动态地在几种算法中选择一种。

相关文章:

使用C/C++编写PHP Extension

【c#教程】C# 数据类型

相关视频:

什么是设计模式-php高级设计模式视频教程

更多相关文章

  1. Kafka 原理以及分区分配策略剖析
  2. 分布式作业系统 Elastic-Job-Lite 源码分析 —— 作业分片策略
  3. 熔断器 Hystrix 源码解析 —— 命令执行(二)之执行隔离策略
  4. 7个 Javascript 面试题及回答策略 [每日前端夜话0x30]
  5. 7个开放式的 HTML 面试题及回答策略 [每日前端夜话0x32]
  6. 7 个开放式 CSS 面试题及回答策略 [每日前端夜话0x2E]
  7. 7 个Web开发工程师面试题和回答策略 [每日前端夜话0x34]
  8. PHP代码优化的53个细节和优化策略
  9. php策略模式和适配器模式的区别

随机推荐

  1. 使用python将图片转换为字符图片
  2. 如何按期执行python脚本?
  3. python 3.3 爬虫之爬取图片
  4. python处理数据,存进hive表
  5. Python笔记-几种取整方式
  6. python 中 字符串转换为数组,字典或表达式
  7. 详解Python中的from..import绝对导入语句
  8. python入门之常见列表、字典知识
  9. 如何使用pip安装Python MySQLdb模块?
  10. 检测Python程序的执行效率