策略模式
- 简介:策略模式属于行为型模式,一个类的行为或其算法可以在运行时更改。
- 意图:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
- 主要解决:在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
- 关键代码:实现同一个接口。
- 优点:
1、算法可以自由切换。
2、使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
3、扩展性良好。 - 缺点:
1、由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。
2、客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。 - 使用场景:比如我们在网站商城购物, 同一件商品面对不同的会员会有不同的价格, 比如普通会员是原件, 中级会员是打九折, 高级会员打八折, 这就是一个策略模式
- 注意事项:如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。
实现
- 我就实现上述那个会员例子, 商品面对不同的会员, 返回不同的价格
- 把这件事分为三个角色
- 环境(Context)角色:持有一个Strategy的引用。
- 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
- 三个角色的关系: 环境角色包含一个抽象策略角色, 可以接受不同的实现了抽象策略角色的具体策略角色
抽象策略角色
//抽象策略角色
public interface Strategy {
/**
* 策略方法
* @param shopPrice 商品原价
* @return 打折后的价格
*/
double strategyInterface(double shopPrice);
}
初级会员策略
//初级会员策略
public class PrimaryMemberStrategy implements Strategy {
/**
* 初级会员返回原件
* @param shopPrice 商品原价
* @return
*/
@Override
public double strategyInterface(double shopPrice) {
return shopPrice;
}
}
中级会员策略
//中级会员策略
public class IntermediateMemberStrategy implements Strategy {
/**
* 中级会员打九折
* @param shopPrice 商品原价
* @return
*/
@Override
public double strategyInterface(double shopPrice) {
return shopPrice * 0.9;
}
}
高级会员策略
public class AdvancedMemberStrategy implements Strategy {
/**
* 高级会员打八折
* @param shopPrice 商品原价
* @return
*/
@Override
public double strategyInterface(double shopPrice) {
return shopPrice * 0.8;
}
}
环境角色
//环境角色
public class Context {
/**
* 策略实现角色
*/
private final Strategy strategy;
/**
* 通过构造方法传入一个具体策略
* @param strategy 策略实现角色
*/
public Context(Strategy strategy) {
this.strategy = strategy;
}
/**
* 获得打折后的价格
* @param shopPrice 商品原件
* @return 打折后的价格
*/
public double getNewPrice(double shopPrice) {
return this.strategy.strategyInterface(shopPrice);
}
}
客户端
public class Client {
public static void main(String[] args) {
//创建需要的策略实现角色
AdvancedMemberStrategy advancedMemberStrategy = new AdvancedMemberStrategy();
//创建打折环境角色
Context context = new Context(advancedMemberStrategy);
//获得打折后的价格
System.out.println(context.getNewPrice(99.99));
}
}
- 总结策略模式就是我们可以通过一个统一的抽象策略接口,策略实现者只需要实现这个接口就可以实现粗略的扩展, 策略使用者也就是环境角色内含一个抽象策略接口, 只需要把传进来的数据进行实现即可, 无需关注其如何实现, 这个和桥接模式有那么点相通之处, 但是对那进行了多策略实现的一个扩展