设计模式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.策略模式的定义 何为策略?比如我们要去某个地方旅游,可以根据具体的实际情况来选择出行的线路. 如果没有时间但是不在乎钱,可以选择坐飞机. 如果没有钱,可以选择坐大巴或者火车. 如果再穷一点,可以选 ...
随机推荐
- 3.集--LinkedTransferQueue得知
近期在阅读开源项目里,发现有几个project都不尽同样地使用LinkedTransferQueue这个数据结构.比方netty,grizzly,xmemcache,Bonecp. Bonecp还扩展 ...
- js拾遗:appendChild 添加移动节点
原文:js拾遗:appendChild 添加移动节点 写js一年多了,一直以为自己很牛逼,开始写各种博文分享,昨天写了一篇<浅谈 IE下innerHTML导致的问题>在看了下面的评论,我才 ...
- JavaEE(1) - Weblogic 服务器管理的数据源
JBoss下载: http://jbossas.jboss.org/downloads http://www.cnblogs.com/xw-cnblogs/articles/2439969.html ...
- select查询原理
原文:select查询原理 我并非专业DBA,但做为B/S架构的开发人员,总是离不开数据库,一般开发员只会应用SQL的四条经典语句:select ,insert,delete,update.但是我从来 ...
- 基于HTTP/2和protobuf的RPC框架:GRPC
谷歌发布的首款基于HTTP/2和protobuf的RPC框架:GRPC Google 刚刚开源了grpc, 一个基于HTTP2 和 Protobuf 的高性能.开源.通用的RPC框架.Protobu ...
- nexus私服linux搭建问题
一.最近搭建nexus私服,从官网下载下来总是报503服务器无效,很是无奈,最后在网上找到一个可以用的 收藏起来,这里给大家共享一下 下载地址:http://pan.baidu.com/s/1kT3U ...
- 汤姆大叔 深入理解JavaScript系列(20):《你真懂JavaScript吗?》答案详解 后六道题答案
原题目地址:http://www.cnblogs.com/TomXu/archive/2012/02/10/2342098.html 答案丰富多彩.我只是记录下自己思考了半天全部的答案. 题目一:找出 ...
- SQL Server 复制 - 发布订阅(SQL Server 数据同步)
原文:SQL Server 复制 - 发布订阅(SQL Server 数据同步) SQL Server的同步是通过SQL Server自带的复制工具来实现的,分发布和订阅2大步. A,复制-发布 发布 ...
- MY WAY程序(十八) 团队开发
1.通信知识 要了解的强哥的移动通信先验知识布局.我和另外一个毕业生有自己的学习,但我真的没有认真看.了解了一下,其余大部分时间在搞nodejs.另外一个应届毕业生则是按着一本电子书 ...
- ASP.NET开发,简化与封装
ASP.NET开发,简化与封装 微软的ASP.NET的开发,就是面向对象的编程,当然前端也能体验至面向对象的话,使用Web控件也必须的. 任一控件,我们均可以在后端.aspx.cs或.aspx.vb程 ...