java设计模式(2)策略模式
2016-07-05 13:40
225 查看
策略模式
策略模式也是常用的设计模式之一,属于对象的行为模式。其定义为:针对一组算法,将算法封装到具有共同接口的独立类中,从而使它们可以互换。此模式让算法的变化独立于使用算法的客户。举个例子,超市要打折促销一批苹果。有半价折扣,有满减折扣,有88折有66折等等不同形式的促销方案,该超市可能这周用半价的方案,下周生意好了可能用88折,过些时也可能用满减。并且今后也可能添加更多方案。这时如何设计出可复用、可扩充、可维护的一组类来表达这种情景呢?
根据策略模式的定义,我们可以把这些打折方法看做一组策略(或算法),将这些算法抽象到一个有打折方法的接口中。每个打折方法都是一个实现了此打折方法的类。代码如下:
/** * 算法的抽象接口 */ public interface Strategy{ //打折方法 double disCount(int price); } /** *方法A :8折 */ public class StrategyA implements Strategy{ @Override public double disCount(int price){ return price*0.8; } } /** *方法B :满100后,多出部分半价 */ public class StrategyB implements Strategy{ @Override public double disCount(int price){ return price<100?price:(price-100)*0.5+100; } } /** *方法C :优惠50 */ public class StrategyC implements Strategy{ @Override public double disCount(int price){ return price-50; } }
以上代码将每种打折促销方法都写成一个类,并拥有统一的父接口。所有实现了策略接口的类在该模式下都称为“具体策略类“,该接口为“抽象策略类”。目标是要实现苹果的不同折扣方案,苹果类又称为“环境角色类“。
public class Apple{ //模拟苹果,在策略模式中此类为“环境角色类” public Apple(){} public Apple(Strategy strategy){ this.strategy=strategy; //通过构造函数给策略实例赋值 } private double price; //价格 private Strategy strategy; //保存该策略接口引用 public void setPrice(double price){ this.price=price; } public double getPrice(){ return price; } public double calculatePrice(){ return strategy.disCount(price); } } public class Test{ public static void main(String []args){ Strategy strategy = new StrategyA(); //在这里更换具体策略 //Strategy strategy = new StrategyB(); //Strategy strategy = new StrategyC(); Apple apple = new Apple(strategy); apple.setPrice(200); int discount = apple.calculatePrice(); System.out.println("折扣后价格:"+discount); } }
在环境角色类中嵌入抽象的策略接口,以便在应用中动态改变所需的打折策略。上面例子中嵌入方式为:在环境角色类中保存一个抽象策略类的变量,在构造函数中为其赋值,当然,也可以直接在折扣方法的参数列表中拥有一个嵌入抽象策略类引用,等到调用该方法时再赋值。如下:
public class Apple{ private double price; //价格 public void setPrice(double price){ this.price=price; } public double getPrice(){ return price; } public double calculatePrice(){ return price; } public double calculatePrice(Strategy strategy){ return strategy.disCount(price); } } public class Test{ public static void main(String []args){ Apple apple = new Apple(); apple.setPrice(200); int discount = apple.calculatePrice(new StrategyA());//在这里更换折扣策略 System.out.println("折扣后价格:"+discount); } }
本人更倾向于使用第二种方式实现策略模式,因其耦合性更低,不用嵌入策略类的变量,不用在构造函数中耦合策略类。在Java API中,关于File类的list()方法(返回该File类底下的文件名或目录名的集组成的数组)即使用了策略模式。list方法有2个版本,如下:
public String[] list(); //没有参数,返回该目录下所有文件名组成的String数组
public String[] list(FilenameFilter filter); //有一个过滤器的参数,FilenameFilter 是一个接口
带参数的list方法返回经过滤器筛选后的数组,FilenameFilter 相当于策略模式中的抽象策略,该接口含有一个选择文件名的方法定义,任何一个实现此接口的类充当此参数,实现自己的过滤效果。FilenameFilter 接口如下:
public interface FilenameFilter { boolean accept(File dir, String name); }
实现具体的过滤策略
public static void main(String[]args){ File file = new File(".");//将当前目录赋值给file //String []list = file.list(filter); filter应当是一个实现了FilenameFilter 接口的类的实例,这里使用匿名内部类实现,如下 String[] list = path.list(new FilenameFilter() { //筛选文件名含有“Hello”的java文件 public boolean accept(File f, String name) { return Pattern.matches("\S*Hello\S*\.java",name); } }); }
关于java的策略模式就讲到这里了,若有不正确的地方还请各位网友指正,联系方式:wthfeng@126.com。
参考文章:
1. 《Head First 设计模式》
2. http://www.cnblogs.com/java-my-life/archive/2012/05/10/2491891.html
相关文章推荐
- 我理解的--java 单例模式
- 我理解的--java工厂模式
- 我理解的--java建造者模式
- 我理解的--java组合模式
- 我理解的--java门面模式
- 我理解的--java策略模式
- 我理解的--java模板方法模式
- 我理解的--java观察者模式
- 我理解的--java备忘录模式
- 我理解的--java中介者模式
- Java设计模式(一) 简单工厂模式不简单
- Java设计模式(十一) 享元模式
- Java设计模式(二) 工厂方法模式
- 从赵本山的小品联想到的Java设计模式
- JAVA设计模式学习第三天 设计模式之Chain of Responsibility——项目篇
- 学习:java设计模式—工厂模式
- 设计模式----简单工厂模式
- Java设计模式 创建模式-工厂模式(Factory)
- Java设计模式 创建模式-原型模式(Prototype)