本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8057654.html,记录一下学习过程以备后续查用。

    一、引言

    今天我们要讲行为型设计模式的第七个模式--策略模式。在现实生活中,策略模式的例子也非常常见,例如:在一个公司中,会有各种工作人员:有普通员工、有软件架构师、有部门经理,当然也有公司的CEO等等。这些工作人员负责的工作不同、担负的职责也不同,报酬也各不相同。

    每种工作人员都有自己的工资,但是不同工种其工资的计算方式是不一样的。如果不采用策略模式来实现这个需求的话,我们可能会这样来做:定义一个工资类,该类有一个属性来标识工作人员的类型,并且有一个计算工资的CalculateSalary()方法,在该方法体内对工作人员类型进行判断,然后通过if-else语句来计算不同类型的工资。这样做确实可以解决这个场景,但是不利于扩展。如果系统后期需要增加一种新的工种时,需对CalculateSalary方法进行修改(再添加一个判断语句),这样明显违背了“开闭原则”。

    此时,我们可以考虑使用策略模式来解决这个问题。既然工资计算方法是这个场景中的变化部分,此时自然想到的是对工资算法进行抽象。不同工种的工资可以用不用的策略算法具体实现,若想得到某个工作人员的工资,使用其对应的工资算法策略进行计算就可以了。

    二、策略模式介绍

    策略模式:英文名称--Strategy Pattern;分类--行为型。

    2.1、动机(Motivate)

    在软件构建过程中,某些对象使用的算法可能多种多样,经常改变。如果将这些算法都编码到对象中,将会使对象变得异常复杂,而且有时候支持不使用的算法也是一个性能负担。如何在运行时根据需要透明地更改对象的算法,将算法与对象本身解耦,从而避免上述问题?

    2.2、意图(Intent)

    定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用它的客户而变化。——《设计模式》GoF

    2.3、结构图(Structure)

C#设计模式学习笔记:(19)策略模式

    2.4、模式的组成

    可以看出,在策略模式的结构图有以下角色:

    1)环境角色(Context):持有一个Strategy类的引用。

        需要使用ConcreteStrategy提供的算法。

        内部维护一个Strategy的实例。

        负责动态设置运行时Strategy具体的实现算法。

        负责跟Strategy之间的交互和数据传递。

    2)抽象策略角色(Strategy):定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。

    3)具体策略角色(ConcreteStrategy):实现了Strategy定义的接口,提供具体的算法实现。

    2.5、策略模式的具体实现

    在现实生活中,策略模式的例子也是很多的,例如:一个公司会有很多工种,每个工种负责的工作不同,其对应的工资计算方法也会不同。我们今天就以工资的计算为例来说明策略模式的使用,实现代码如下:

C#设计模式学习笔记:(19)策略模式
    class Program
    {
        /// <summary>
        /// 环境角色--相当于Context类型
        /// </summary>
        public sealed class SalaryContext
        {
            public ISalaryStrategy SalaryStrategy { get; set; }

            public SalaryContext(ISalaryStrategy strategy)
            {
                SalaryStrategy = strategy;
            }

            public void GetSalary(double income)
            {
                SalaryStrategy.CalculateSalary(income);
            }
        }

        /// <summary>
        /// 抽象策略角色--相当于Strategy类型
        /// </summary>
        public interface ISalaryStrategy
        {
            //工资计算
            void CalculateSalary(double income);
        }

        /// <summary>
        /// 程序员的工资--相当于具体策略角色ConcreteStrategyA
        /// </summary>
        public sealed class ProgrammerSalary : ISalaryStrategy
        {
            public void CalculateSalary(double income)
            {
                Console.WriteLine("程序员的工资是:基本工资(" + income + ")底薪(" + 8000 + ")+加班费+项目奖金(10%)");
            }
        }

        /// <summary>
        /// 普通员工的工资--相当于具体策略角色ConcreteStrategyB
        /// </summary>
        public sealed class NormalPeopleSalary : ISalaryStrategy
        {
            public void CalculateSalary(double income)
            {
                Console.WriteLine("普通员工的工资是:基本工资(" + income + ")底薪(3000)+加班费");
            }
        }

        /// <summary>
        /// CEO的工资--相当于具体策略角色ConcreteStrategyC
        /// </summary>
        public sealed class CEOSalary : ISalaryStrategy
        {
            public void CalculateSalary(double income)
            {
                Console.WriteLine("CEO的工资是:基本工资(" + income + ")底薪(20000)+项目奖金(20%)+公司股票");
            }
        }

        static void Main(string[] args)
        {
            #region 策略模式
            //普通员工的工资
            SalaryContext context = new SalaryContext(new NormalPeopleSalary());
            context.GetSalary(3000);

            //CEO的工资
            context.SalaryStrategy = new CEOSalary();
            context.GetSalary(6000);

            Console.Read();
            #endregion
        }
    }
View Code

相关文章:

  • 2021-08-20
  • 2022-03-03
  • 2021-12-08
  • 2021-08-31
  • 2021-11-03
  • 2021-12-28
猜你喜欢
  • 2021-09-20
  • 2021-10-24
  • 2021-07-24
  • 2021-09-13
  • 2021-12-28
  • 2021-10-16
相关资源
相似解决方案