1、什么是策略模式
我们要出一次远门我们有多种交通方式,每一种方式都是一种策略,我们支付买东西,WX ,zfb ,yl 我们选着没哪个,就是一个策略
意图:将算法封装成一个算法中,让每个算法可以相互替换。
主要解决: 多种算法相似的情况下避免了很多的 if else
其中,Context是上下文,用一个ConcreteStrategy来配置,维护一个对Strategy对象的引用,
Strategy是策略类,用于定义所有支持算法的公共接口;ConcreteStrategy是具体策略类,封装了具体的算法或行为,继承于Strategy。
1. Context上下文
Context上下文角色,也叫Context封装角色,起承上启下的作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变,上下文调用各种算法到底执行什么,
2. 策略角色
Strategy:抽象策略角色,是对策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性,即抽象策略角色规定算法统一行为,
3. 具体策略角色
用于实现抽象策略中的操作
1. 上下文类
它起到承上启下的作用,具体的执行哪个算法
public class Context {
private Strategy strategy;
public Context(Strategy strategy) {
this.strategy = strategy;
}
public void exeCon() {
strategy.CashSuper();
}
}
2. 策略角色
也为抽象类,定义一个接口或者,抽象类,抽出方法供子类使用,抽象策略角色规定算法统一行为,
public interface Strategy {
void CashSuper();
}
3.具体的策略角色
具体封装的算法
public class BooKing implements Strategy {
@Override
public void CashSuper() {
System.out.println("预定");
}
}
public class Discount implements Strategy {
@Override
public void CashSuper() {
System.out.println("折扣");
}
}
public class Original implements Strategy {
@Override
public void CashSuper() {
System.out.println("原价");
}
}
public class PinTuan implements Strategy {
@Override
public void CashSuper() {
System.out.println("拼团优惠");
}
}
4.测试类
public class TestStr {
public static void main(String[] args) {
Context context = new Context(new BooKing());
context.exeCon();
}
}
这样实现一个简单地策略但是我们要调用哪一个策略我们还有要用 if else 去判断,我们把上下文改造一下,这样我们实现一个工厂以后的扩展只需要维护这个Context的扩展就可以了
public class ContextFac {
private static Map<String,Strategy> map = new HashMap<String, Strategy>();
private static final Strategy original = new Original();//默认没有优惠
static {
//把所有的具体策略角色放到map里面
map.put(PromoKey.BooKing,new BooKing());
map.put(PromoKey.Discount,new Discount());
map.put(PromoKey.Original,new Original());
map.put(PromoKey.PinTuan,new PinTuan());
}
private ContextFac() {
}
//根据传过来的key是执行
public static Strategy getPromoKey(String key){
Strategy strategy = map.get(key);
return strategy == null ? original : strategy;
}
//内部类定义
private interface PromoKey{
String BooKing="BooKing";
String Discount="Discount";
String Original="Original";
String PinTuan="PinTuan";
}
//得到所有key,可以返回到页面上,供用户选择
public static Set<String> getPromotionKeys(){
return map.keySet();
}
}
测试类
public class TestStr {
public static void main(String[] args) {
//得到所有的key
Set<String> promotionKeys = getPromotionKeys();
System.out.println(promotionKeys);
for (String promotionKey : promotionKeys) {
Strategy promoKey = getPromoKey(promotionKey);
promoKey.CashSuper();
}
测试结果
[Discount, PinTuan, BooKing, Original]
折扣
拼团优惠
预定
原价
这样改造的我们就要知道每个具体的行为策略是什么 ,但是策略类会增多,所有策略类都需要对外暴露。
使用场景:
- 一个系统要动态的选择一种算法像上面案例一样
- 如果一个对象有多个类,只是在乎对象的行为,可以用策略模式动态的去选择一种去执行