一 初探
策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
二 使用场景
支付方式算法策略、交通方式算法策略、不同顾客支付算法策略等等。以下支付方式选择策略举例。
- 策略接口
/**
* 策略接口(抽象类也可以)
*/
public interface PayStrategy {
public long pay(long price);
}
- 策略1
public class AliPayStrategy implements PayStrategy{
@Override
public long pay(long price) {
System.out.println("选择阿里支付");
//业务
System.out.println("支付成功,此时支付:" +price);
return price;
}
}
- 策略2
public class JDPayStrategy implements PayStrategy {
@Override
public long pay(long price) {
System.out.println("选择京东支付");
//业务
System.out.println("支付成功,此时支付:" +price);
return price;
}
}
- 策略3
public class WechatPayStrategy implements PayStrategy {
@Override
public long pay(long price) {
System.out.println("选择微信支付");
//业务
System.out.println("支付成功,此时支付:" +price);
return price;
}
}
- 具体支付:支付方式本身有客户端维护,省去了if或者switch等判断
public class Price {
//持有具体策略对象
private PayStrategy strategy;
/**
* 构造函数,传入具体策略对象
* @param strategy
*/
public Price(PayStrategy strategy) {
this.strategy = strategy;
}
/**
* 策略方法
* @param price
* @return
*/
public long payPrice(long price){
return this.strategy.pay(price);
}
}
- 客户端调用:选择策略,执行策略
/**
* 客户端:1,选择具体的策略 2,执行策略
* @param args
*/
public static void main(String[] args) {
PayStrategy payStrategy = new JDPayStrategy();
long price = new Price(payStrategy).payPrice(10000);
System.out.println(price);
}
三 总结
- 策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。
- 策略模式仅仅封装算法,提供新的算法插入到已有系统中,以及老算法从系统中“退休”的方法,策略模式并不决定在何时使用何种算法。在什么情况下使用什么算法是由客户端决定的。
- 经常见到的是,所有的具体策略类都有一些公有的行为。这时候,就应当把这些公有的行为放到共同的抽象策略角色Strategy类里面。当然这时候抽象策略角色必须要用Java抽象类实现,而不能使用接口。
-
策略模式的优点
(1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
(2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
- 策略模式的缺点
(1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
(2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。