策略模式

策略模式定义:

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

The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同额方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。

策略模式UML类图:

角色分析:

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

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

Context(应用场景):内部维护一个Strategy的实例,负责动态设置运行时Strategy具体的实现算法。 具体实例如下(一个超市促销时采用不同的策略,比如打折,返利等): 抽象策略类

namespace DesignPattern.策略模式
{
    //现金收费抽象类
    abstract class CashSuper
    {
        /*
         * 现金收取超类的抽象方法,收取现金,参数为原价,返回为当前价
        */
        public abstract double AcceptCash(double cash);
    }
}

具体策略类

namespace DesignPattern.策略模式
{
    //正常收费子类
    class CashNormal : CashSuper
    {
        public override double AcceptCash(double cash)
        {
            return cash;
        }
    }

    //打折收费子类
    class CashRebate : CashSuper
    {
        private double moneyRebate = 1;
        /*
         * 打折收费,初始化时,必须要输入折扣费,如八折(0.8)
        */
        public CashRebate(double moneyRebate)
        {
            this.moneyRebate = moneyRebate;
        }
        public override double AcceptCash(double cash)
        {
            return moneyRebate * cash;
        }
    }

    //返利收费子类
    class CashReturn : CashSuper
    {
        private double moneyCondition = 0;//返利的条件
        private double moneyReturn = 0;//返利的金额

        public CashReturn(double moneyCondition, double moneyReturn)
        {
            this.moneyCondition = moneyCondition;
            this.moneyReturn = moneyReturn;
        }

        public override double AcceptCash(double cash)
        {
            double result = cash;
            if (cash > moneyCondition)
            {
                result = cash - Math.Floor(cash / moneyCondition) * moneyReturn;
            }
            return result;
        }
    }
}

应用场景类

namespace DesignPattern.策略模式
{
    class CashContext
    {
        private CashSuper cashContext;

        public CashContext(String type)
        {
            switch (type)
            {
                case "正常收费":
                    cashContext = new CashNormal();
                    break;
                case "打8折":
                    cashContext = new CashRebate(0.8);
                    break;
                case "满300反100":
                    cashContext = new CashReturn(300, 100);
                    break;
           }
        }

        public double GetResult(double cash)
        {
            return cashContext.AcceptCash(cash);
        }

    }
}

测试类

namespace DesignPattern.策略模式
{
    class Strategy
    {
        public static void Main()
        {
            double cash = 330;
            double result = 0;
            CashContext context = null;

            context = new CashContext("打8折");
            result = context.GetResult(cash);
            Console.WriteLine("打八折后的价格:{0}", result);

            context = new CashContext("满300反100");
            result = context.GetResult(cash);
            Console.WriteLine("满300反100的价格:{0}", result);
        }
        
    }
}

策略模式的使用场景

1. 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。

2. 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。

3. 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 虚拟机下安装CentOS无法上网的解决方案

    我使用VMware虚拟机安装Ubuntu和CentOS,都使用NAT模式连接网络,但是Ubutun可以正常上网,而CentOS不能连接到网络。

    卡尔曼和玻尔兹曼谁曼
  • Leetcode: Excel Sheet Column Number

    Related to question Excel Sheet Column Title

    卡尔曼和玻尔兹曼谁曼
  • Ubuntu下Postgresql卸载出错的解决办法

    其实感觉是第一个命令删除了dpkg关于postgresql的元数据信息,然后使用autoremove命令的时候,dpkg以为postgresql没有安装,然后提...

    卡尔曼和玻尔兹曼谁曼
  • 【算法】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题

    有若干个城市,任何两个城市之间的距离都是确定的,现要求一旅行商从某城市出发必须经过每一个城市且只在一个城市逗留一次,最后回到出发的城市,问如何事先确定一条最短的...

    短短的路走走停停
  • 洛谷题解P4326 求圆的面积

    https://www.luogu.org/problemnew/show/P4326

    海天一树
  • C语言 第八章 函数、指针与宏

    一、函数 函数是一个包含完成一定功能的执行代码段。我们可以把函数看成一个"黑盒子", 你只要将数据送进去就能得到结果, 而函数内部究竟是如何工作的的, 外部程序...

    张果
  • SPOJ NWERC11B Bird tree

    题意:根据公式进行分析,当该数字小于1说明往左边走,当数字大于1说明往右边走 #include<stdio.h> int main() { int ...

    用户1624346
  • 每个程序员都该知道的 5 个定律 转

    这篇文章中,我将介绍我每次设计或实现软件时出现在我脑海的 5 个定律。其中有些和开发有关,有些和系统组织有关。它们可以帮助你成为合格的软件工程师。

    wuweixiang
  • 使用Kotlin 1.1.5 的REPL 来简单分析一下Java 9 中的$ jmod list java.base.jmod《Kotlin极简教程》正式上架:

    命令行列出了 模块 java.base.jmod 中所有文件(.class文件, .dat, .jar, .cfg, .dylib 等 )共 5761个文件...

    一个会写诗的程序员
  • 记一次神奇的sql查询经历,group by慢查询优化

    现网出现慢查询,在500万数量级的情况下,单表查询速度在30多秒,需要对sql进行优化,sql如下:

    梁规晓

扫码关注云+社区

领取腾讯云代金券