实例探索Java模式之路——策略模式
来源:互联网 发布:淘宝卖家版怎么登陆 编辑:程序博客网 时间:2024/05/22 14:55
策略模式
1、策略模式属于对象的行为模式。是针对的一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得他们可以互相替换。
策略模式使得算法可以在不影响到客户端的情况下发生变化。策略模式是对算法的包装。
把使用算法的责任和算法本身分割开,委派给不同的对象管理。
简单来说就是,准备一组算法,并将每一个算法封装起来,使得他们可以互相互换。
3、结构:
环境:持有一个抽象策略的引用。
抽象策略:给出所有的具体策略所需的接口
具体策略:包装了相关的算法或行为。
4、一个简单的实例:
//环境类,持有抽象策略的引用
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
// 策略方法
public void contextInterface() {
strategy.strategyInterface();
}
}
//抽象策略类
public abstract class Strategy {
// 策略方法
public abstract void strategyInterface();
}
//具体策略1
public class ConcreteStrategy1 extends Strategy {
@Override
public void strategyInterface() {
System.out.println("我是具体策略算法1");
}
}
//具体策略2
public class ConcreteStrategy2 extends Strategy {
@Override
public void strategyInterface() {
System.out.println("我是具体策略算法2");
}
}
//客户端
public class client {
public static void main(String[] args) {
// 决定使用什么策略
Strategy strategy = new ConcreteStrategy2();
Context c = new Context(strategy);
c.contextInterface();
}
}
5、策略模式应该注意的地方:
1、所有的具体策略都有一些公有的行为,应当把这些公有的行为放在抽象策略角色Strategy类里面。这时时候抽象角色必须用java抽象类实现,而不使用Java接口。
2、策略模式每一个时刻只能使用一个策略对象,有时候一个应用程序同时与几个策略对象相联系。在应用程序启动时,所有的策略对象就已经被创立出来,而应用程序可以在几个策略对象之间调换。
6、
一个计算图书折扣的例子。客户端通过不同算法得到相应的折扣金额。
算法1:有些图书没有折扣,折扣对象返回0作为折扣值。
算法2:有些图书固定值为5元的折扣。
算法3:图书提供一个百分比的折扣。
//图书折扣抽象策略类
public abstract class DiscountStrategy {
protected float price = 0;// 书本单价
protected int copies = 0;// 书本数量
// 策略方法
public abstract float calculateDiscount();
// 构造方法
public DiscountStrategy(float price, int copies) {
this.price = price;
this.copies = copies;
}
}
//具体折扣类,没有折扣的图书
public class NoDiscountStrategy extends DiscountStrategy {
// 构造方法
public NoDiscountStrategy(float price, int copies) {
super(price, copies);
}
// 策略方法,没有折扣
@Override
public float calculateDiscount() {
return 0;
}
}
//具体折扣类,没有折扣的图书
public class FlatRateStrategy extends DiscountStrategy {
private float amount = 0.0f;// 固定折扣金额
// 构造方法
public FlatRateStrategy(float price, int copies) {
super(price, copies);
}
public float getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
// 策略方法,固定折扣金额书本水量*固定折扣金额
@Override
public float calculateDiscount() {
return copies * amount;
}
}
//具体折扣类,一个百分比的折扣
public class PercentageStrategy extends DiscountStrategy {
private float percent = 0.0f;// 折扣百分比
// 构造方法
public PercentageStrategy(float price, int copies) {
super(price, copies);
}
public float getPercent() {
return percent;
}
public void setPercent(float percent) {
this.percent = percent;
}
@Override
public float calculateDiscount() {
return copies * (1.0f - percent) * price;
}
}
import java.text.NumberFormat;
//客户端,策略模式并不负责使用哪一种策略,应当由客户端自己决定在什么情况下使用哪一种具体策略
public class client extends Thread {
public static void main(String[] args) {
// 没有折扣的图书
NoDiscountStrategy nodiscountStrategy = new NoDiscountStrategy(10.f, 10);
// 折扣总额
System.out.println("折扣的折扣金额"
+ formateCurrency(nodiscountStrategy.calculateDiscount()));
// 固定折扣的图书
FlatRateStrategy flatRateStrategy = new FlatRateStrategy(20.0f, 5);
flatRateStrategy.setAmount(5);
// 折扣总额
System.out.println("折扣的折扣金额"
+ formateCurrency(flatRateStrategy.calculateDiscount()));
// 百分比折扣
PercentageStrategy percentageStrategy = new PercentageStrategy(50f, 10);
percentageStrategy.setPercent(0.8f);// 8折
System.out.println("折扣的折扣金额"
+ formateCurrency(percentageStrategy.calculateDiscount()));// 折扣总额
}
// 金额格式化
private static String formateCurrency(double amnt) {
return NumberFormat.getCurrencyInstance().format(amnt);
}
}
什么图书使用什么折扣并不是策略模式决定的,而是由客户端决定的。
策略模式仅仅是封装算法,不决定何时使用何种算法。
折扣的折扣金额¥0.00
折扣的折扣金额¥25.00
折扣的折扣金额¥100.00
我们会发现上面的代码缺少一个环境角色(环境:持有一个抽象策略的引用)
//环境类,持有抽象策略的引用
public class Context {
private DiscountStrategy strategy;
public Context(DiscountStrategy strategy) {
this.strategy = strategy;
}
// 策略方法
public float contextInterface() {
return strategy.calculateDiscount();
}
}
import java.text.NumberFormat;
public class client extends Thread {
// 金额格式化
private static String formateCurrency(double amnt) {
return NumberFormat.getCurrencyInstance().format(amnt);
}
public static void main(String[] args) {
// 没有折扣的图书
NoDiscountStrategy nodiscountStrategy = new NoDiscountStrategy(10.f, 10);
Context cn = new Context(nodiscountStrategy);
System.out.println(formateCurrency(cn.contextInterface()));
// 固定折扣的图书
FlatRateStrategy flatRateStrategy = new FlatRateStrategy(20.0f, 5);
flatRateStrategy.setAmount(5);
Context cf = new Context(flatRateStrategy);
System.out.println(formateCurrency(cf.contextInterface()));
PercentageStrategy percentageStrategy = new PercentageStrategy(50f, 10);
percentageStrategy.setPercent(0.8f);// 8折
Context cp = new Context(percentageStrategy);
System.out.println(formateCurrency(cp.contextInterface()));
}
}
7、策略模式的使用场景:
要达到某一个目的,根据具体的实际情况,选择合适的方法。适合于实现某一个功能有多种方案可以选择的情景。
8、策略模式优缺点:
优点:
(1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
(2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
缺点:
(1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
(2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。
阅读全文
0 0
- 实例探索Java模式之路——策略模式
- 实例探索Java模式之路——建造模式
- 实例探索Java模式之路——适配器模式
- 实例探索Java模式之路——合成模式
- 实例探索Java模式之路——装饰模式
- 实例探索Java模式之路——代理模式
- 实例探索Java模式之路——门面模式
- 实例探索Java模式之路——不变模式
- 实例探索Java模式之路——观察者模式
- 实例探索Java模式之路——命令模式
- 实例探索Java模式之路——状态模式
- 实例探索Java模式之路——序言
- 实例探索Java模式之路——原始模型
- 实例探索Java模式之路——简单工厂模式
- 实例探索Java模式之路——工厂方法模式
- 实例探索Java模式之路——抽象工厂模式
- 实例探索Java模式之路——单例模式
- 实例探索Java模式之路——多例模式
- shell脚本
- JAVA中ListIterator和Iterator详解与辨析
- 将二叉搜索树转换成一个排序的双向链表--中序线索化的变型。
- Spring Cloud微服务(1)之 Spring Boot
- 正则表达式
- 实例探索Java模式之路——策略模式
- people are able to buy the same products anywhere in the world
- 复合井盖功能越来越多样化
- asp完整显示数据代码
- 使用util命名空间定义集合
- LVS同步连接状态信息(IPVS Connection Synchronization)
- linux应用开发基础(一)GCC编译器、动态库、静态库使用
- HDU 2222 Keywords Search(AC自动机)
- bash: 一键安装Chrome