设计模式18---设计模式之策略模式(Strategy)(行为型)
1.场景模拟
简单的报价管理系统:
对于普通用户和新用户报全价
对于老客户统一折扣5%
对于大客户统一折扣10%
2.不用模式的解决方案
package demo16.strategy.example2;
/**
* 价格管理,主要完成计算向客户所报价格的功能
*/
public class Price {
/**
* 报价,对不同类型的,计算不同的价格
* @param goodsPrice 商品销售原价
* @param customerType 客户类型
* @return 计算出来的,应该给客户报的价格
*/
public double quote(double goodsPrice,String customerType){
if("普通客户".equals(customerType)){
return this.calcPriceForNormal(goodsPrice);
}else if("老客户".equals(customerType)){
return this.calcPriceForOld(goodsPrice);
}else if("大客户".equals(customerType)){
return this.calcPriceForLarge(goodsPrice);
}
//其余人员都是报原价
return goodsPrice;
}
/**
* 为新客户或者是普通客户计算应报的价格
* @param goodsPrice 商品销售原价
* @return 计算出来的,应该给客户报的价格
*/
private double calcPriceForNormal(double goodsPrice){
System.out.println("对于新客户或者是普通客户,没有折扣");
return goodsPrice;
}
/**
* 为老客户计算应报的价格
* @param goodsPrice 商品销售原价
* @return 计算出来的,应该给客户报的价格
*/
private double calcPriceForOld(double goodsPrice){
System.out.println("对于老客户,统一折扣5%");
return goodsPrice*(1-0.05);
}
/**
* 为大客户计算应报的价格
* @param goodsPrice 商品销售原价
* @return 计算出来的,应该给客户报的价格
*/
private double calcPriceForLarge(double goodsPrice){
System.out.println("对于大客户,统一折扣10%");
return goodsPrice*(1-0.1);
}
}
3.有何问题?
会经常有这样的需要,在公司周年庆的时候,所有的客户额外增加3%的折扣,在换季的时候普通用户额外增加3%的折扣,然后过了促销时间,价格又要涨回来,那么这个价格类将会非常的庞大,而且,方法非常的多。
看到这,朋友们很快就想到:如何实现才能让价格类中的计算报价的算法,很容易的实现可维护,可扩展,而且可以动态的切换变化呢?
4.使用策略模式来解决问题
4.1策略模式定义
定义一系列的算法,把他们一个个封装起来,并且可以使他们相互替换,本模式使得算法可独立于使用它的客户而变化。
4.2策略模式的结构图
4.3策略模式示例代码
package demo16.strategy.example3; /**
* 策略,定义算法的接口
*/
public interface Strategy {
/**
* 某个算法的接口,可以有传入参数,也可以有返回值
*/
public void algorithmInterface();
}
*********************************************************************
package demo16.strategy.example3; /**
* 实现具体的算法
*/
public class ConcreteStrategyA implements Strategy { public void algorithmInterface() {
//具体的算法实现
} }
*********************************************************************
package demo16.strategy.example3; /**
* 实现具体的算法
*/
public class ConcreteStrategyB implements Strategy { public void algorithmInterface() {
//具体的算法实现
} } package demo16.strategy.example3; /**
* 实现具体的算法
*/
public class ConcreteStrategyC implements Strategy { public void algorithmInterface() {
//具体的算法实现
}
}
*********************************************************************
package demo16.strategy.example3; /**
* 上下文对象,通常会持有一个具体的策略对象
*/
public class Context {
/**
* 持有一个具体的策略对象
*/
private Strategy strategy;
/**
* 构造方法,传入一个具体的策略对象
* @param aStrategy 具体的策略对象
*/
public Context(Strategy aStrategy) {
this.strategy = aStrategy;
}
/**
* 上下文对客户端提供的操作接口,可以有参数和返回值
*/
public void contextInterface() {
//通常会转调具体的策略对象进行算法运算
strategy.algorithmInterface();
}
}
5.使用策略模式重写实例
package demo16.strategy.example4; /**
* 策略,定义计算报价算法的接口
*/
public interface Strategy {
/**
* 计算应报的价格
* @param goodsPrice 商品销售原价
* @return 计算出来的,应该给客户报的价格
*/
public double calcPrice(double goodsPrice);
}
************************************************************************
package demo16.strategy.example4;
/**
* 具体算法实现,为新客户或者是普通客户计算应报的价格
*/
public class NormalCustomerStrategy implements Strategy{
public double calcPrice(double goodsPrice) {
System.out.println("对于新客户或者是普通客户,没有折扣");
return goodsPrice;
}
}
***********************************************************************
package demo16.strategy.example4;
/**
* 具体算法实现,为老客户计算应报的价格
*/
public class OldCustomerStrategy implements Strategy{
public double calcPrice(double goodsPrice) {
System.out.println("对于老客户,统一折扣5%");
return goodsPrice*(1-0.05);
}
}
***********************************************************************
package demo16.strategy.example4;
/**
* 具体算法实现,为大客户计算应报的价格
*/
public class LargeCustomerStrategy implements Strategy{
public double calcPrice(double goodsPrice) {
System.out.println("对于大客户,统一折扣10%");
return goodsPrice*(1-0.1);
}
}
***********************************************************************
package demo16.strategy.example4;
/**
* 价格管理,主要完成计算向客户所报价格的功能
*/
public class Price {
/**
* 持有一个具体的策略对象
*/
private Strategy strategy = null;
/**
* 构造方法,传入一个具体的策略对象
* @param aStrategy 具体的策略对象
*/
public Price(Strategy aStrategy){
this.strategy = aStrategy;
}
/**
* 报价,计算对客户的报价
* @param goodsPrice 商品销售原价
* @return 计算出来的,应该给客户报的价格
*/
public double quote(double goodsPrice){
return this.strategy.calcPrice(goodsPrice);
}
}
***********************************************************************
package demo16.strategy.example4; public class Client {
public static void main(String[] args) {
//1:选择并创建需要使用的策略对象
Strategy strategy = new LargeCustomerStrategy();
//2:创建上下文
Price ctx = new Price(strategy); //3:计算报价
double quote = ctx.quote(1000);
System.out.println("向客户报价:"+quote);
}
}
6.模式讲解
6.1要点
功能:把具体的算法从具体的业务处理中独立出来,把他们实现成为单独的算法类,从而形成一系列的算法,并让这些算法可以相互替换。
策略算法是相同行为的不同实现
什么时候选用:多个if-else语句的时候就可以选用
6.2策略模式的调用顺序示意图
首先客户端选择并创建具体的策略对象
其次创建上下文
最后调用上下文的方法来执行功能了
6.3当添加新的策略时候
只需要动下面代码,是不是很简单,很方便呢?
//1:选择并创建需要使用的策略对象
Strategy strategy = new LargeCustomerStrategy();
6.4另一种策略模式调用示意图
6.5策略模式优缺点
优点:定义一系列算法,避免使用多重条件语句,更好的扩展性
缺点:客户端必须了解每种策略的不同,增加了对象数目,只适合扁平的算法结构(地位平等的算法)
6.6设计模式的本质
分离算法,选择实现
设计模式18---设计模式之策略模式(Strategy)(行为型)的更多相关文章
- 设计模式(二)策略模式(Strategy)
1.分析项目中变化部分与不变部分 2.多用组合,少用继承:用行为类组合,而不是行为的继承 案例: 第一步,把行为抽象为接口 package top.littlepage.designPattern.S ...
- HeadFirst设计模式读书笔记(1)-策略模式(Strategy Pattern)
策略模式(Strategy Pattern): 定义了了算法簇,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户端. 第一个设计原则:找出应用中可能需要变化之处,把他们独立 ...
- 设计模式(二) 策略模式Strategy
策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理,我个人的理解是,具有相同行为不同的行为模式,比如走路,有人速度3m/s,有人100m/s,把他们的具体行走和对象本身 ...
- Headfirst设计模式的C++实现——策略模式(Strategy)
前言 最近在学习<Headfirst设计模式>,里面的例子都是Java的.但是我对Java并不熟悉,所以试着用C++来实现书中的例子. 先来看看Duck以及子类 Duck.h #inclu ...
- 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)
在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了“工厂模式”.“策略模式”.“状态模式”等.当然在重构时,有的地 ...
- 【转】设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成 ...
- 设计模式 ( 十八 ) 策略模式Strategy(对象行为型)
设计模式 ( 十八 ) 策略模式Strategy(对象行为型) 1.概述 在软件开发中也经常遇到类似的情况,实现某一个功能有多种算法或者策略,我们能够依据环境或者条件的不同选择不同的算法或者策略来完毕 ...
- 乐在其中设计模式(C#) - 策略模式(Strategy Pattern)
原文:乐在其中设计模式(C#) - 策略模式(Strategy Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 策略模式(Strategy Pattern) 作者:webabc ...
- 反馈法学习设计模式(一)——策略模式Strategy Pattern
简介(Introduction) 之前学习Java8实战时,遇到一个很好的策略模式示例.便想着借着这个示例结合反馈式的方法来,学习策略设计模式,也以便后面反复琢磨学习. 首先我们通过练习,逐步写出符合 ...
- JavaScript设计模式 Item 7 --策略模式Strategy
1.策略模式的定义 何为策略?比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但是不在乎钱,可以选择坐飞机. 如果没有钱,可以选择坐大巴或者火车. 如果再穷一点,可以选 ...
随机推荐
- Swiftly语言学习1
单纯值: 1.let常量声明,var声明变量(同时宣布福值,编译器会自己主动判断出类型) var myVariable = 42 myVariable 50 let myConstant = 42 l ...
- Openstack & Hadoop结合项目Sahara
Openstack 项目Sahara,主要是用来搭建Hadoop集群,利用虚拟出来的计算资源,高速搭建Hadoop集群. Sahara项目与OPenstack其它项目的关系: 图片转自:http:// ...
- 【百度地图API】如何进行地址解析与反地址解析?——模糊地址能搜索到精确地理信息!
原文:[百度地图API]如何进行地址解析与反地址解析?--模糊地址能搜索到精确地理信息! 摘要: 什么是地址解析? 什么是反地址解析? 如何运用地址解析,和反地址解析? 可以同时运用地址解析,和反地址 ...
- Uva 409-Excuses, Excuses!(串)
Judge Ito is having a problem with people subpoenaed for jury duty giving rather lame excuses in ord ...
- WCF消息交换模式之双工通讯(Duplex)
WCF消息交换模式之双工通讯(Duplex) 双工通讯Duplex具有以下特点: 1它可以在处理完请求之后,通过请求客户端中的回调进行响应操作 2.消息交换过程中,服务端和客户端角色会发生调换 3.服 ...
- POI导出大量数据的简单解决方案(附源码)-Java-POI导出大量数据,导出Excel文件,压缩ZIP(转载自iteye.com)
说明:我的电脑 2.0CPU 2G内存 能够十秒钟导出 20W 条数据 ,12.8M的excel内容压缩后2.68M 我们知道在POI导出Excel时,数据量大了,很容易导致内存溢出.由于Excel ...
- linux学习书籍
linux学习书籍推荐 网上看到的,做个标记.没研究过,仅供参考 linux编程学习 inux 学习书目推荐 Linux基础 1.<Linux与Unix Shell 编程指南> C语 ...
- ThinkPad E431/E531 ubuntu 14.04 安装无线网卡驱动
ubuntu系统装好之后无限网卡驱动并不能用.须要自己下载无线网卡驱动.以下是最简单的方法: sudo apt-get install linux-headers-generic build-esse ...
- codeforces #262 DIV2 C称号Present(二分法+贪婪)
职务地址:http://codeforces.com/contest/460/problem/C 这个题是用二分枚举最小值.然后推断是否能在规定的次数内使得全部的数都达到这个值.推断的时候要用贪心的方 ...
- 【MS SQL】数据库维护计划之数据库备份(二)
原文:[MS SQL]数据库维护计划之数据库备份(二) 上篇[MS SQL]数据库维护计划之数据库备份(一) 说了数据库备份的一些概念后,这篇以HRP_KQYY数据库备份为例,进行备份计划设置. 考虑 ...