策略模式及简单Java案例代码实现
说明:本文是《大话设计模式》的学习记录及结合网上相关信息编写,原书代码例子采用C#编写,本文采用Java稍加改写。如有不当,欢迎指正,共同进步。
1.策略模式概述:
策略模式(Pattern:Strategy)属于行为型模型,是指对一系列的算法定义,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
2.策略模式包含的角色及其职责:
(1)抽象策略角色[Strategy]:策略类,定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,
Context使用这个接口调用不同的算法,一般使用接口或抽象类实现。
(2)具体策略类[ConcreteStrategy]:实现了Strategy定义的接口,包装了相关的算法和行为,提供具体的算法实现。
(3)上下文角色[Context]:持有一个策略类的引用,最终给客户端调用。
①需要使用ConcreteStrategy提供的算法。
②内部维护一个Strategy的实例。
③负责动态设置运行时Strategy具体的实现算法。
④负责跟Strategy之间的交互和数据传递。
3.策略模式的设计原则及UML类图:
(1)设计原则:变化的抽象成接口,面向接口编程而不是面向实现编程。
(2)UML类图:
4.Java案例代码:
(1)抽象策略角色:
package StrategyPattern;/*** 现金收费抽象类*/
public abstract class CashSuper {//现金收取超类的抽象方法,收取现金,参数为原价,返回为当前价public abstract double acceptCash(double money);
}
(2)具体策略类:
package StrategyPattern;/*** 正常收费子类,继承现金收费抽象类*/
public class CashNormal extends CashSuper {@Overridepublic double acceptCash(double money) {//正常收费,返回原价return money;}}package StrategyPattern;/*** 打折收费子类,继承现金收费抽象类*/
public class CashRebate extends CashSuper {private double moneyRebate = 1;public CashRebate(String moneyRebate) {//打折收费,初始化时,必须输入折扣率,如八折,就是0.8this.moneyRebate = Double.valueOf(moneyRebate);}@Overridepublic double acceptCash(double money) {return money*moneyRebate;}}package StrategyPattern;/*** 返利收费子类,继承现金收费抽象类*/
public class CashReturn extends CashSuper {private double moneyCondition = 0; //返利条件private double moneyReturn = 0; //返利值//返利收费,初始化时必须要输入返利条件和返利值,比如满300返100public CashReturn(String moneyCondition, String moneyReturn) {this.moneyCondition = Double.valueOf(moneyCondition);this.moneyReturn = Double.valueOf(moneyReturn);}@Overridepublic double acceptCash(double money) {if (money>=moneyCondition) {//若大于返利条件,则需要减去返利值return money-Math.floor(money/moneyCondition)*moneyReturn;}return money;}}
(3)上下文角色:策略与简单工厂结合
package StrategyPattern;
/*** CashContext类* 策略与简单工厂结合*/
public class CashContext {private CashSuper cs; //声明一个CashSuper对象//通过构造方法,传入收费策略再生产具体的收费策略类public CashContext(String rates) {switch (rates) {case "正常收费":cs = new CashNormal();break;case "满1000减100":cs = new CashReturn("1000", "100");break;case "打8折":cs = new CashRebate("0.8");break;default:break;}}//根据收费策略的不同,获得计算结果public double getResult(double money) {return cs.acceptCash(money);}}
(4)客户端测试代码:
package StrategyPattern;/*** 客户端代码*/
public class Test1 {public static void main(String[] args) {int number = 300; //商品数量int price = 10; //商品单价Normal(number, price); //正常收费Rebate(number, price); //打折收费Return(number, price); //满减收费}public static void Normal(int number, int price) {CashContext ccNormal = new CashContext("正常收费");double result = ccNormal.getResult(number*price);System.out.println("正常收费:商品单价为:" + price + "元,商品数量为:" + number + "件,应付款:" + result + "元。");}public static void Rebate(int number, int price) {CashContext ccRebate = new CashContext("打8折");double result = ccRebate.getResult(number*price);System.out.println("打折收费:商品单价为:" + price + "元,商品数量为:" + number + "件,应付款:" + result + "元。");}public static void Return(int number, int price) {CashContext ccReturn = new CashContext("满1000减100");double result = ccReturn.getResult(number*price);System.out.println("打折收费:商品单价为:" + price + "元,商品数量为:" + number + "件,应付款:" + result + "元。");}}
(5)客户端测试代码打印结果:
5.策略模式的优缺点及使用场景:
(1)优点:
①策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。
②策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。
③使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
(2)缺点:
①客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
②策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。
(3)应用场景:
①多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
②需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
③对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
策略模式及简单Java案例代码实现相关推荐
- java工厂模式式代码_简单工厂模式及其简单Java案例代码实现
说明:本文是<大话设计模式>的学习记录及结合网上相关信息编写,原书代码例子采用C#编写,本文采用Java稍加改写.若有不当,欢迎指正,共同进步.java 1.简单工厂模式概述:设计模式 简 ...
- 原型模式及简单Java案例代码实现
说明:本文是<大话设计模式>的学习记录及结合网上相关信息编写,原书代码例子采用C#编写,本文采用Java稍加改写.如有不当,欢迎指正,共同进步. 1.原型方法模式概述: 原型模式(Patt ...
- 策略模式与简单工厂模式区别(转)
最近一直在抽时间研究设计模式,之前对设计模式也有一定的了解,但是都没有平心静气的去研究过,只是了解了一些皮毛,最近打算再深入研究一下,重新打开了设计模式的数据,对之前的疑问一个个的刨根问底,今天看了简 ...
- 大话设计模式-策略模式与简单工厂模式
来源:http://blog.csdn.net/wulingmin21/article/details/6712684 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策 ...
- 策略模式和简单工厂+策略模式
策略模式:以相同的方式调用所有算法,工厂让仕途藏认识到了两个类:工厂类和对象类,而策略模式只有一个Context类来维护. 策略模式: 简单工厂+策略模式 源码地址:http://pan.baidu. ...
- Java设计模式之策略模式(UML类图分析+代码详解)
大家好,我是一名在算法之路上不断前进的小小程序猿!体会算法之美,领悟算法的智慧~ 希望各位博友走过路过可以给我点个免费的赞,你们的支持是我不断前进的动力!! 加油吧!未来可期!! 本文将介绍java设 ...
- 【设计模式】策略模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )
文章目录 一.策略模式简介 二.策略模式适用场景 三.策略模式优缺点 四.策略模式与其它设计模式 五.策略模式代码示例 1.促销策略接口 2.满减促销策略 3.返现促销策略 4.空促销策略 5.促销策 ...
- [设计模式] ------ 策略模式实战:java中替代if-else的大段逻辑
java中用策略模式替代if-else的大段逻辑 问题: java本来是一门以面向对象为主的语言,但很多人嘴上说着java面向对象,然后除了表映射实体之外,其他的还是面向过程的思路. 就比如今天要说的 ...
- springboot 使用工厂模式+策略模式替代多重if 案例
项目背景: 由于做的是物联网项目,现在需要实现的是网关入网+子设备注册:网关有3个逻辑,分别为首次入网.解绑后同一个人入网(恢复).解绑后换人入网(换人).子设备注册: 原先写法是: if(type ...
最新文章
- 贾扬清加盟AI开发者大会!早鸟票抢购正式开启
- 好玩,新版微信除了“炸屎”,还可以和她亲亲
- WIN7下黑苹果懒人版硬盘安装not a HFS partition注意问题
- 初学 Python(十三)——匿名函数
- 持续集成mysql_DevOps安装、部署持续集成
- 双11尾款人的续命丸哪里找?送3本精神食粮助你快速回血
- spark reduce与reduceByKey的区别
- TypeError: unsupported type for timedelta days component: Series
- Django项目 BBS论坛
- pigoss BSM 售前使用问题总结2(FAQ)
- wamp php 7.0,wamp如何尝鲜php7
- Android根据pdf模板生成pdf文件
- css裁剪属性----clip-path
- 对传统优化算法的一些总结(上)
- cube的意思中文翻译_cube是什么意思_cube的翻译_音标_读音_用法_例句_爱词霸在线词典...
- 人生之路小游戏代码2
- 低调收藏,5大免费资源网站!网友:够用一辈子啦
- java图片点击事件_java中想要点击一个button然后jlabel上就显示出图片,button事件监听该怎么写。...
- 逗女朋友玩的C语言程序,怎么哄异地女朋友睡觉 男生赶快学起来
- CF978F Mentors