行为类模式(九):策略(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地往返都 ...
随机推荐
- python之函数用法setdefault()
# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之函数用法setdefault() #D.get(k,d) #说明:k在D中,则返回 D[K], ...
- python 什么叫迭代
# -*- coding: cp936 -*- #xiaodeng #python 27 #什么叫迭代 #如果给定一个list/tuple,可以通过for循环遍历出来,这种遍历我们称之为迭代 #案例3 ...
- 从JSF看XPages的优点
我们都知道XPages基于JSF,或者可以说XPages是JSF标准的实现(implementation)之一.JSF从2004年的1.0到现在的2.0,已经经历了很大的变化和发展.XPages最初开 ...
- Lambda表达式树
1.常量表达式树 Func< + ); 使用表达式树的方式 ConstantExpression a = Expression.Constant(); ConstantExpression b ...
- 转:TCP/IP协议栈的基本工作原理
转载自:http://jasonccie.blog.51cto.com/2143955/422966 TCP/IP是互联网的核心协议,也是大多数网络应用的核心协议.就前面一段时间面试中问到的TCP/I ...
- Mysql 将结果保存到文件 从文件里运行sql语句 记录操作过程(tee 命令的使用)
1. 有时候我们可能须要记录我们对mysql的操作过程,这时我们能够使用mysql的tee命令 1)第一种情况是在链接数据库的时候使用tee >mysql -u root -p --te ...
- Android开发环境——连接驱动ADB相关内容汇总
Android开发环境将分为SDK相关内容.Eclipse ADT相关内容.模拟器AVD相关内容.调试器DDMS相关内容.日志LogCat相关内容.连接驱动ADB相关内容.内存泄露检测工具MAT相关 ...
- mysql--SQL编程(关于mysql中的日期) 学习笔记2
一.mysql数据库中的date1.DATETIME和DATE:DATETIME占用8个字节,日期范围为"1000-01-01 00:00:00"到"9999-12-31 ...
- ios持久化存储
前言 iOS中常用的持久化存储方式有好几种: 偏好设置(NSUserDefaults) plist文件存储 归档 SQLite3 Core Data 沙盒 每个iOS应用都有自己的应用沙盒(应用沙盒就 ...
- VirtualBox虚拟机增加CentOS根目录容量 LVM扩容
对于目前的网络开发者来说,比较好的搭档就是Win7+VirtualBox+CentOS的组合,既可以发挥Linux强大的网络服务功能,也可以有效的隔离各项服务拖慢系统,影响系统的运行,对于新手来说可以 ...