策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的用户。何谓算法呢?它是一种描述程序行为的语言,广泛应用于计算机科学领域,是一种让程序最为简洁的思考方式。

一、组成:

1.抽象策略角色: 策略类,通常由一个接口或者抽象类实现。

2.具体策略角色:包装了相关的算法和行为。

3.环境角色:持有一个策略类的引用,最终给客户端调用。

二、应用场景:

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

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

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

三、优缺点:

1.优点:

恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。将每个算法都封装起来,并且使它们之间可以互换,客户端调用它们的时候互不影响。从而降低了系统的耦合度,提高了扩展性和可重用性,易于测试和维护。

2.缺点:

策略模式只适用于客户端知道所有的算法或行为的情况。策略模式造成很多的策略类,每个具体策略类都会产生一个新类,可以使用享元模式来减少对象的数量。

四、策略模式vs简单工厂模式:

   工厂模式是创建型模式,关注对象的创建。策略模式是行为型模式,关注行为的封装。简单工厂模式是根据不同的条件返回一个适合的类给你使用,然后调用者使用工厂类返回的类去完成相应的操作。而策略模式是首先创建一个想使用的类实例,然后实例被当作参数传递进去,既而通过该实例去调用不用的算法。

五、代码示范:

某超市平时正常收费,周六日打八折,周年庆满300返100。下面我们利用已经学到的策略模式与简单工厂相结合编写一个收银程序。

1.抽象策略类:

//现金收取父类
abstract class CashSuper
{//抽象方法:收取现金,参数为原价,返回为当前价public abstract double acceptCash(double money);
}

2.具体策略角色:

 //正常收费,继承CashSuperclass CashNormal : CashSuper{public override double acceptCash(double money){return money;}}
 //打折收费,继承CashSuperclass CashRebate : CashSuper{private double moneyRebate = 1d;//初始化时,必需要输入折扣率,如八折,就是0.8public CashRebate(string moneyRebate){this.moneyRebate = double.Parse(moneyRebate);}public override double acceptCash(double money){return money * moneyRebate;}}
 //返利收费,继承CashSuperclass CashReturn : CashSuper{private double moneyCondition = 0.0d;private double moneyReturn = 0.0d;//初始化时必须要输入返利条件和返利值,比如满300返100,则moneyCondition为300,moneyReturn为100public CashReturn(string moneyCondition, string moneyReturn){this.moneyCondition = double.Parse(moneyCondition);this.moneyReturn = double.Parse(moneyReturn);}public override double acceptCash(double money){double result = money;//若大于返利条件,则需要减去返利值if (money >= moneyCondition)result = money - Math.Floor(money / moneyCondition) * moneyReturn;return result;}}

3.环境角色:

class CashContext
{CashSuper cs = null;//根据条件返回相应的对象public CashContext(string type){switch (type){case "正常收费":CashNormal cs0 = new CashNormal();cs = cs0;break;case "满300返100":CashReturn cr1 = new CashReturn("300", "100");cs = cr1;break;case "打8折":CashRebate cr2 = new CashRebate("0.8");cs = cr2;break;}}public double GetResult(double money){return cs.acceptCash(money);}
}

4.客户端:

  //客户端窗体程序(主要部分)double total = 0.0d;private void btnOk_Click(object sender, EventArgs e){//利用简单工厂模式根据下拉选择框,生成相应的对象CashContext csuper = new CashContext(cbxType.SelectedItem.ToString());double totalPrices = 0d;//通过多态,可以得到收取费用的结果totalPrices = csuper.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));total = total + totalPrices;lbxList.Items.Add("单价:" + txtPrice.Text + " 数量:" + txtNum.Text + " "+ cbxType.SelectedItem + " 合计:" + totalPrices.ToString());lblResult.Text = total.ToString();}

5.窗体展示:

6.如果不使用策略模式,只用简单工厂实现,会怎样呢?请看客户端的代码。

//客户端窗体程序(主要部分)double total = 0.0d;private void btnOk_Click(object sender, EventArgs e){//利用简单工厂模式根据下拉选择框,生成相应的对象CashSuper csuper = CashFactory.createCashAccept(cbxType.SelectedItem.ToString());double totalPrices = 0d;//通过多态,可以得到收取费用的结果totalPrices = csuper.acceptCash(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));total = total + totalPrices;lbxList.Items.Add("单价:" + txtPrice.Text + " 数量:" + txtNum.Text + " "+ cbxType.SelectedItem + " 合计:" + totalPrices.ToString());lblResult.Text = total.ToString();}

如果不使用策略模式,超市需要经常性地更改收费方式,每次维护和扩展都要去改动CashFactory,重新编译部署代码,这样就很麻烦了。策略模式定义了一系列算法(收费方式)的方法,这些算法完成的都是相同的工作,那就是GetResult。应用简单工厂把实例化具体策略类的过程由客户端转移到Context类中,这样客户端只需认识一个类CashContext,具体的收费算法彻底地与客户端分离,从而降低了耦合度,易于维护。

有了这样的的程序,收银员即使没学过数学也能胜任这份工作,只需在组合框中选择正确的收费方式,然后去扫码就可以了。超市打折时,不必去数据库中一个一个改动商品的价格,也不必耗费时间和劳动力去给商品重新贴价格了。

变是永远不变的,如果超市要打九折、满200返50呢,如何避免更改CashContext中的代码呢?这就要用到我们以后要学的反射技术了,办法总是比困难多的。一款好的软件虽然是看不见摸不着的,但它们发挥的作用却是不可估量的,所以好好学设计模式吧,设计出优秀的软件,为人民服务!

设计模式------策略模式相关推荐

  1. Python设计模式-策略模式

    Python设计模式-策略模式 代码基于3.5.2,代码如下; #coding:utf-8 #策略模式class sendInterface():def send(self,value):raise ...

  2. 关于设计模式——策略模式-Strategy Pattern

    文章目录 1 策略模式 1.1 模拟鸭子 1.2 设计原则 1.3 整合行为 1.4 模拟鸭子代码的代码 1.5 动态设定行为 1.6 重新查看整体 1.7 继承和组合 1.8 总结 1.9 优劣期间 ...

  3. [设计模式] ------ 策略模式

    策略模式 它定义了算法家族,分别封装起来,让他们直接可以互相替换,此模式让算法的变化,不会影响到使用算法的客户 其实很简单,可能很多人都用到了,只不过还不知道这就是策略模式而已. 比如定义一个接口A, ...

  4. java 策略模式 促销_java设计模式——策略模式

    一. 定义与类型 定义:针对一组算法,将每一种算法都封装到具有共同接口的独立的类中,从而是它们可以相互替换.策略模式的最大特点是使得算法可以在不影响客户端的情况下发生变化,从而改变不同的功能.当代码中 ...

  5. Springboot 使用设计模式- 策略模式

    前言 直白点,什么场景我们需要使用到设计模式- 策略模式. 在平常的springboot项目里面做CRUD,我们的习惯性基本是 一个mapper,一个service,一个serviceImpl. 但是 ...

  6. 李建忠设计模式——策略模式Strategy

    目录 1.策略模式定义 1.动机 2.模式定义 3.结构 2.实现例子 1.问题描述 2.代码实现 3.要点总结 4.参考 1.策略模式定义 1.动机 软件构建过程中,某些对象使用的算法可能多种多样, ...

  7. 15. 星际争霸之php设计模式--策略模式

    题记 ============================================================================== 本php设计模式专辑来源于博客(jy ...

  8. Java设计模式-策略模式作业

    Java设计模式-策略模式作业,所有类和接口均在一个package内 文章目录 前言 一.作业内容 二.具体实现 1.类图 2.Strategy接口 3.PreCopyStrategy类 4.Post ...

  9. 设计模式-策略模式2.0

    设计模式-策略模式2.0 前面文章我们说过了传统的策略模式的实现,本文我们简单说下设计模式中的升级版的策略模式,策略模式2.0. 代码实现 talk is cheap show me the code ...

  10. 设计模式-策略模式(Strategy)-Java

    设计模式-策略模式(Strategy)-Java 目录 文章目录 1.前言 2.示例案例-电影票打折方案 3.策略模式概述 3.1.策略模式定义 3.2.策略模式结构 3.3.策略模式结构图中角色 3 ...

最新文章

  1. 什么是导师负责制_为什么一个导师是不够的
  2. 基础 - #pragma pack (n) 设置对齐方式
  3. OpenGL抗锯齿实例
  4. 处理网络请求qs、图片转base64的优劣
  5. win7电脑内存信息的查看方法
  6. ViewState 与 静态变量的 区别
  7. 贴片晶振脚位_贴片晶振的焊接方法和注意事项
  8. html网页视频播放器代码,HTML网页制作视频播放器现成代码
  9. BIOS 虚拟化技术
  10. java坦克大战互相碰撞_加强版坦克大战(java版)
  11. 本地erp与云erp系统的差别
  12. 元宇宙GOD新纪元打通元宇宙
  13. 后台管理系统纯前端模板
  14. 英语单词如何看字母划分音节
  15. 解决md文件中本地图片链接失效的方法
  16. 汝之蜜糖,吾之砒霜— 聊聊软件开发中的最佳实践
  17. 水水笔-first(04/29)
  18. 计算机网络虚电路数据报,虚电路服务和数据报服务
  19. 上海国家会计学院(SNAI)亚利桑那州立大学(ASU)合作办学EMBA项目打造兼具金融财务和服务管理专长的领袖人才!
  20. unescape,escape加密解密js

热门文章

  1. 计算机配置认识,硬件配置 认识计算机硬件组成
  2. 如何使用ABBYY FineReader 14编辑文本
  3. 如何设计推荐系统架构?
  4. nacos + seata
  5. linux 删除多个软件下载,linux强制删除软件强力清除残留配置
  6. Django-用户功能设计与实现
  7. unigui发布_uniGUI试用笔记(十一) ---UNIDBGRID
  8. 小小滑块可笑可笑-安卓滑块验证码通杀方案研究(2)
  9. 19条优雅Python编程技巧
  10. 免安装Oracleclient和PL/SQL