前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【愚公系列】2021年12月 二十三种设计模式(二十一)-策略模式(Stragety Pattern)

【愚公系列】2021年12月 二十三种设计模式(二十一)-策略模式(Stragety Pattern)

作者头像
愚公搬代码
发布2022-12-01 09:32:26
2420
发布2022-12-01 09:32:26
举报
文章被收录于专栏:历史专栏

文章目录


前言

提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


提示:以下是本篇文章正文内容,下面案例可供参考

一、策略模式(Stragety Pattern)

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

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

二、使用步骤

角色

1、抽象策略(Strategy)

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

2、具体策略(Concrete Strategy)

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

3、环境类(Context)

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

示例

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

代码语言:javascript
复制
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计算相应收入的个人所得税。

代码语言:javascript
复制
public class Level0 : Tax {

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

}

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

代码语言:javascript
复制
public class Level1 : Tax {

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

}

1级个人所得税阶梯。

代码语言:javascript
复制
public class Level2 : Tax {

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

}

2级个人所得税阶梯。

代码语言:javascript
复制
public class Level3 : Tax {

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

}

3级个人所得税阶梯。

代码语言:javascript
复制
public class Level4 : Tax {

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

}

4级个人所得税阶梯。

代码语言:javascript
复制
public class Level5 : Tax {

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

}

5级个人所得税阶梯。

代码语言:javascript
复制
public class Level6 : Tax {

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

}

6级个人所得税阶梯。

代码语言:javascript
复制
public class Level7 : Tax {

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

}

7级个人所得税阶梯。

代码语言:javascript
复制
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实现类来计算相应阶梯的个人所得税。

代码语言:javascript
复制
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();
    }

}

以上是调用方的代码,Calculate经过特殊处理以支持方法链。以下是这个案例的输出结果:

代码语言:javascript
复制
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、一个系统需要动态地在几种算法中选择一种。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-08-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 前言
  • 一、策略模式(Stragety Pattern)
  • 二、使用步骤
    • 角色
      • 示例
      • 总结
        • 优点
          • 缺点
            • 使用场景
            相关产品与服务
            腾讯云 TI 平台
            腾讯云 TI 平台(TencentCloud TI Platform)是基于腾讯先进 AI 能力和多年技术经验,面向开发者、政企提供的全栈式人工智能开发服务平台,致力于打通包含从数据获取、数据处理、算法构建、模型训练、模型评估、模型部署、到 AI 应用开发的产业 + AI 落地全流程链路,帮助用户快速创建和部署 AI 应用,管理全周期 AI 解决方案,从而助力政企单位加速数字化转型并促进 AI 行业生态共建。腾讯云 TI 平台系列产品支持公有云访问、私有化部署以及专属云部署。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档