行为类模式(九):策略(Strategy)
定义
针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
UML

优点
- 策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码转移到父类里面,从而避免重复的代码。
- 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为。如果不是用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。决定使用哪一种算法或采取哪一种行为的逻辑就和算法或行为的逻辑混合在一起,从而不可能再独立演化。继承使得动态改变算法或行为变得不可能。
- 使用策略模式可以避免使用多重条件转移语句。多重转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重转移语句里面,比使用继承的办法还要原始和落后。
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道所有的算法或行为的情况。
- 策略模式造成很多的策略类,每个具体策略类都会产生一个新类。有时候可以通过把依赖于环境的状态保存到客户端里面,而将策略类设计成可共享的,这样策略类实例可以被不同客户端使用。换言之,可以使用享元模式来减少对象的数量。
应用场景
- 多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
- 需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
- 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。
示例
考虑一个销售的场景,针对不同的客户销售的产品有不同的优惠。
Java
public class Main
{
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);
} /**
* 价格管理,主要完成计算向客户所报价格的功能
*/
public static 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);
}
} /**
* 策略,定义计算报价算法的接口
*/
public interface Strategy
{
/**
* 计算应报的价格
* @param goodsPrice 商品销售原价
* @return 计算出来的,应该给客户报的价格
*/
double calcPrice(double goodsPrice);
} /**
* 具体算法实现,为新客户或者是普通客户计算应报的价格
*/
public static class NormalCustomerStrategy implements Strategy
{
public double calcPrice(double goodsPrice)
{
System.out.println("对于新客户或者是普通客户,没有折扣");
return goodsPrice;
}
} /**
* 具体算法实现,为老客户计算应报的价格
*/
public static class OldCustomerStrategy implements Strategy
{
public double calcPrice(double goodsPrice)
{
System.out.println("对于老客户,统一折扣5%");
return goodsPrice * (1 - 0.05);
}
} /**
* 具体算法实现,为大客户计算应报的价格
*/
public static class LargeCustomerStrategy implements Strategy
{
public double calcPrice(double goodsPrice)
{
System.out.println("对于大客户,统一折扣10%");
return goodsPrice * (1 - 0.1);
}
}
}
行为类模式(九):策略(Strategy)的更多相关文章
- 行为型设计模式之模板方法(TEMPLATE METHOD)模式 ,策略(Strategy )模式
1 模板方法(TEMPLATE METHOD)模式: 模板方法模式把我们不知道具体实现的步聚封装成抽象方法,提供一些按正确顺序调用它们的具体方法(这些具体方法统称为模板方法),这样构成一个抽象基类.子 ...
- 设计模式C++实现(1)——策略(Strategy)模式
目录 策略模式 应用案例 实现的关键 Talk is cheap,let's See The Code 设计思想 参考 策略模式 策略模式定义了一系列算法和行为(也就是策略),他们可以在运行时相互替换 ...
- 策略(strategy)模式
Head First一书中对于策略(strategy)模式的正式定义是:策略模式定义了算法族,分别封装起来,让他们之间可以相互替换,此模式让算法的变化独立于使用算法的客户. 为了介绍这个算法,书中讲了 ...
- C++设计模式实现--策略(Strategy)模式
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/L_Andy/article/details/30489331 一. 举例说明 曾经做了一个程序,程序 ...
- Java 实现策略(Strategy)模式
策略模式:行为型模式 将同一行为,不同的处理算法分别封装起来.让它们之间能够互相替换 1. 定义一个超类型接口,及 行为方法 2. 定义不同的实现类,实现该行为的 不同的算法 /** * 策略模式:针 ...
- 设计模式 策略-Strategy,装饰-Decorator,观察者-Observer
重温了Head First 3个设计模式.提炼一下思想,笔记如下. 策略-Strategy 当一个类或类族中重复实现某些同类的方法(behavior)时,考虑使用策略模式. 该模式是将Behavior ...
- Provider Pattern提供者模式和策略模式
http://www.codeproject.com/Articles/18222/Provider-Pattern Introduction Provider pattern is one of t ...
- Android设计模式之命令模式、策略模式、模板方法模式
命令模式是其它很多行为型模式的基础模式.策略模式是命令模式的一个特例,而策略模式又和模板方法模式都是算法替换的实现,只不过替换的方式不同.下面来谈谈这三个模式. 命令模式 将一个请求封装为一个对象,从 ...
- GoF23种设计模式之行为型模式之策略模式
传送门 ☞ 轮子的专栏 ☞ 转载请注明 ☞ http://blog.csdn.net/leverage_1229 1概述 定义一系列算法,把它们一个个都封装起来,并且让它们可以相互 ...
- 策略模式、策略模式与Spring的碰撞
策略模式是GoF23种设计模式中比较简单的了,也是常用的设计模式之一,今天我们就来看看策略模式. 实际案例 我工作第三年的时候,重构旅游路线的机票查询模块,旅游路线分为四种情况: 如果A地-B地往返都 ...
随机推荐
- 无法启动此程序,因为计算机中丢失 api-ms-win-crt-stdio-l1-1-0.dll 解决
问题描述 最近用一台Windows Server 2012 R2系统的机器的时候碰到了这个问题. 因为在网上看了很多解决方案,都没有很好的解决.所以记录一下这个问题的解决. 之前使用VS2013编译出 ...
- 了解 node.js
原文为: 我们为什么要使用NodeJS 写的好,就收藏于此,供学习之用. 科普文一则,说说我对NodeJS(一种服务端JavaScript实现)的一些认识,以及我为什么会向后端工程师推荐NodeJS. ...
- Android 仿知乎创意广告
代码地址如下:http://www.demodashi.com/demo/14904.html 一.概述 貌似前段时间刷知乎看到的一种非常有特色的广告展现方式,即在列表页,某一个Item显示背后部分广 ...
- 【CAS单点登录视频教程】 第03集 -- 配置 tomcat的 ssl
目录 ----------------------------------------- [CAS单点登录视频教程] 第06集[完] -- Cas认证 学习 票据认证FormsAuthenticati ...
- Ubuntu常用命令大全[显示桌面]
Ubuntu常用命令大全 查看软件xxx安装内容 #dpkg -L xxx 查找软件 #apt-cache search 正则表达式 查找文件属于哪个包 #dpkg -S filename apt-f ...
- df看到的文件系统容量跟parted看到的分区容量差别较大的解决方法
下午同事在自己的开发机上遇到题目说到的问题,它看到挂在到/dev/sda磁盘分区5上的ext4文件系统的容量显著小于该分区的大小 df看到的文件系统容量: #df -h /dev/sda5 Files ...
- iOS设置圆角的四种方法
小小圆角问题,正常情况下,我们不需要过多关心,但当屏幕内比较多的时候,还是有必要了解下性能问题的 一.设置CALayer的cornerRadius 这是最常用的,也是最简单的. cornerRadiu ...
- tf.gfile
一.功能和目的 tf.gfile模块定义在tensorflow/python/platform/gfile.py,但其源代码实现主要位于tensorflow/tensorflow/python/lib ...
- 简单的Java串口通讯应答示例
java串口通讯第一次使用,找的资料都比较麻烦,一时没有理出头绪,自己在示例的基础上整理了一个简单的应答示例,比较简陋,但演示了java串口通讯的基本过程. package com.garfield. ...
- cmake3.8X64编译opencv3.2出现opencv_ffmpeg、opencv_ffmpeg_64、ippicv_windows_20151201.zip无法下载问题解决方案
cmake版本:cmake3.8.0 开发环境:Visual Studio 2017 x64 解决方法:1.在opencv安装目录下sources\3rdparty\ffmpeg\ffmpeg.cma ...