策略(Strategy)模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法时的处理策略。简单来说,策略模式定义了一个算法家族,并让这些算法可以互换。
传统模式是通过继承处理多种算法或行为。该方式需要大量的子类,每一个子类提供一个不同的算法或行为。但是,这样一来算法或行为的使用者就和算法或行为本身混在一起。继承使得动态改变算法或行为变得不可能(每一个子类只能实现特定的算法)。
策略模式是对一系列算法的封装,即:为所有的算法定义一个抽象的算法接口(可以是接口,也可以是抽象类),并由具体的策略对象对算法进行实现。具体的算法选择交由具体策略类决定(具体策略类持有策略接口的引用)。
本模式的核心思想是:多态(面向接口编程),组合。【替代继承关系】
1. 传统模式【通过继承实现】
1.1 抽象类【Duck.java】
将共有的方法抽到这个类里面。(该类作为超类,其它类可以继承该类,实现对抽象类方法的继承或重写)
public abstract class Duck { public abstract void swim(); public void scream() { //TODO } }
1.2 实体对象类【FlyDuck.java】
继承抽象类,实现自己的特有逻辑
public class FlyDuck extends Duck { @Override public void swim() { // TODO } }
1.3 Demo
public static void main(String[] args) { FlyDuck duck = new FlyDuck(); duck.siwm(); }
2. 策略模式
将对象分为三种角色:1.抽象策略角色,2.具体策略角色,3.环境角色
2.1 抽象策略角色
为算法定义一个抽象的算法接口
public interface PriceStrategy { BigDecimal getCurrentPrice(BigDecimal price) throws Exception; }
2.2 具体策略角色
实现抽象策略角色,根据具体的业务需求,实现特定的算法
public class NewYearPriceStrategy implements PriceStrategy{ @Override public BigDecimal getCurrentPrice(BigDecimal price) throws Exception { if(price == null){ throw new Exception("Prince is null.Please Check."); } BigDecimal discount = new BigDecimal(0.5); return price.multiply(discount); } }
2.3 环境角色
策略的外部封装类,或者说策略的容器类。根据不同策略执行不同的行为。
public class Commodity { private BigDecimal price;
//策略角色的引用,多态原理 private PriceStrategy strategy; public Commodity(BigDecimal price, PriceStrategy strategy) { super(); this.price = price; this.strategy = strategy; } public BigDecimal getCurrentPrince() throws Exception{ if(strategy == null){ throw new Exception("Prince Calculator is null. Please check."); } return strategy.getCurrentPrice(price); } }
2.4 Demo
public class Demo { public static void main(String[] args) throws Exception { Commodity commodity = new Commodity(new BigDecimal(124.00),new NewYearPriceStrategy()); System.out.println(commodity.getCurrentPrince()); } }
3. 补充
3.1 继承是在编译时静态决定类的行为,组合是在运行时动态地拓展对象的行为。而且,通过动态地组合对象,可以写新的代码添加新功能,而无须修改现有的代码(出现Bug的概率会变低)。
4. 参考资料
4.1 北风网在线培训《策略模式》
4.2 百度百科《策略模式》
4.3 O'Reilly《Head First设计模式》