不知道策略模式的可以先查看:策略模式
假设一个场景:商场打折,根据折扣来计算打折后的价格
假设可以采用 9折、8折、7折 这三种折扣
再假设两个角色:
- 老板(也就是我们程序员自己,写打折的方法)
- 顾客(也就是调用者,来买东西时调用打折的方法)
顾客怎么根据当天的折扣来获取打折后的价格呢?
不使用策略模式时:
很简单,老板的源代码这样写就行:
if(9折) return money*0.9;
else if(8折) return money*0.8;
else if(7折) return money*0.7;
那么如果现在要加一种新的折扣:6折,只需老板要在源代码加一行就行:
if(9折) return money*0.9;
else if(8折) return money*0.8;
else if(7折) return money*0.7;
else if(6折) return money*0.6;
可问题是现在要加 100 种折扣,岂不是要再加100行 else if?这样显然有两个严重的问题
- 丑陋,代码观感差
- 每次增加新的折扣都需要修改源代码
使用策略模式:
策略模式解决的第一个问题就是:
消除繁杂的 if else
根据策略模式的定义,我们需要这些东西:
- 老板类:Store(相当于策略模式里的 Context)
- 策略接口:Strategy
- 具体的实现类:9Strategy(打9折)、8Strategy(打8折)、7Strategy.(打7折)…
- 顾客:Client
原来顾客 Client 调用老板 Store 的折扣方法时,只需要把钱给老板就行了。
现在则是除了钱,还需要自己带着相应的折扣策略,就能获得打折后的钱。
打9折的策略 9Strategy 的代码:
public double discount(int money){
return money*0.9;
}
Client 的代码:
// 顾客带着 money 来,打9折策略
Store store = new Store(money, new 9Strategy());
double discountedMoney = store.getMoney();
Store 的代码:
// 现在老板只需要调用策略的 discount() 方法就行
public double getMoney(){
return strategy.discount();
}
没错,现在老板的代码再也不用改了,再也不用写那些 if else 了!
也由此引出了第二个优点:
解耦
现在要加新的折扣时只需要新建一个对应的策略类就行了,不用去修改源代码了!符合开闭原则
控制反转
上面我们说到了,现在顾客要自己带着折扣策略来买东西了。也就是说,原本具体执行打几折,是由程序员控制的(也就是一开始那一堆 if else 代码),现在老板仅提供折扣策略,具体执行打几折由方法的的调用者控制了!