java设计模式之策略模式
- 格式:pdf
- 大小:112.06 KB
- 文档页数:3
java设计模式之策略模式介绍
意图: 定义⼀系列的算法,把它们⼀个个封装起来, 并且使它们可相互替换。
解决问题: 在有多种算法相似的情况下,使⽤ if...else 所带来的复杂和难以维护(简⽽⾔之消除if分⽀过多问题)
指导思想
开闭原则、迪⽶特法则、依赖倒置原则
问题场景
公司有节⽇活动,为每个员⼯分发奖⾦。经理(及以上)发5000,普通员⼯2000。
不使⽤策略模式
// 经理
String manage = "manage";
// 普通员⼯
String clerk = "clerk";
Scanner scanner = new Scanner(System.in);
String input = scanner.next();
if(input.equals(manage)){
System.out.println("经理,得5000奖⾦");
}else if(input.equals(clerk)){
System.out.println("其他员⼯,2000元奖⾦");
}
这样做把具体的活动奖⾦分发算法暴露给调⽤⽅,造成维护困难。
此时⽼板说,活动不发奖⾦了,改成聚餐,送购物卡等等。你要再修改复杂的逻辑。
第⼀次优化版
针对上述问题,活动奖⾦分发算法不再暴露给调⽤⽅,封装到统⼀的接⼝。并编写对应实现类,代码如下:
1. 奖⾦分发策略接⼝
public interface BonusStrategy{
/**
* 奖⾦分发具体策略
*/
void bonusDistribution();
}
1. ⼀等奖(经理级以上)具体奖励策略
public class FirstPrize implements BonusStrategy{
@Override
public void bonusDistribution(){
System.out.println("经理,⼀等奖,5000元");
}
}
3 .⼆等奖(普通员⼯)具体奖励策略
public class FirstPrize implements BonusStrategy{
@Override
public void bonusDistribution(){
System.out.println("经理,⼀等奖,5000元");
}
}
1. 调⽤⽅代码: public static void main(String[] args){
// 经理
String manage = "manage";
String clerk = "clerk";
Scanner scanner = new Scanner(System.in);
BonusStrategy bonusStrategy = null;
System.out.println("输⼊你的岗位");
String input = scanner.next();
if(input.equals(manage)){
bonusStrategy = new FirstPrize();
}else if(input.equals(clerk)){
bonusStrategy = new SecondPrize();
}
bonusStrategy.bonusDistribution(); }
此时⽼板发炎,经理不再是奖励5000元了,是送⼀辆车,只需要更改 FirstPrize.java即可,调⽤⽅代码⽆需更改。
but,⽼板⼜发炎了,在经理之上有新增⼀档特等奖,⽤于奖励特别优秀的经理,奖⾦⼀万。。此时代码如下。
1. 新增⼀个特等奖策略,并实现奖⾦策略接⼝
public class GrandPrize implements BonusStrategy{
@Override
public void bonusDistribution(){
System.out.println("特等奖,奖励⼀万");
}
}
1. 调⽤⽅也要做修改,主要新增⼀个if分⽀
public static void main(String[] args){
// 经理
String manage = "manage";
String clerk = "clerk";
String greatGod = "greatGod";
Scanner scanner = new Scanner(System.in);
BonusStrategy bonusStrategy = null;
System.out.println("输⼊你的岗位");
String input = scanner.next();
if(input.equals(manage)){
bonusStrategy = new FirstPrize();
}else if(input.equals(clerk)){
bonusStrategy = new SecondPrize();
}else if(input.equals(greatGod)){
bonusStrategy = new GrandPrize();
}
bonusStrategy.bonusDistribution();
}
* 此时我们改动了调⽤⽅代码,添加if分⽀,耦合度过⾼。
第⼆次优化版
上述⽅法已经实现了算法内容的透明性,⼀定程度上实现了解耦,但策略数量增加时,客户端还是要添加if分⽀实现相应的修改。
1. 创建静态⼯⼚
如果具体策略实现类交由客户端指定,那么if分⽀就⼀直会存在,最好的办法是结合静态⼯⼚,把对象创建交由⼯⼚类来完
成。 static final Map
static {
STRATEGY_MAP.put("manage",new FirstPrize());
STRATEGY_MAP.put("clerk",new SecondPrize());
STRATEGY_MAP.put("greatGod",new GrandPrize());
}
/**
* 获取具体策略
* @param post
* @return
*/
public static BonusStrategy getStrategy(String post){
return STRATEGY_MAP.get(post);
}
1. 消灭客户端(调⽤⽅)的if分⽀
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
BonusStrategy bonusStrategy = null;
System.out.println("输⼊你的岗位");
String input = scanner.next();
BonusStrategy strategy = StrategyFactory.getStrategy(input);
strategy.bonusDistribution();
}
此时,如果业务有变,我们的系统会如何应对呢?
1. 修改奖⾦分发算法:只需修改对应的策略实现类。
2. 增加奖⾦分发策略:新增⼀个策略实现策略接⼝,修改静态⼯⼚在map添加新策略。
两种情况客户端代码都不⽤更改,也不存在if分⽀。
最终版
上述⽅法已经最⼤程度的降低耦合度,但还是有瑕疵,⼯⼚接收的参数是string类型,存在硬编码问题。可以进⼀步优化。
总结
1. 策略模式主要⽬的是封装算法,使之对客户端透明,消灭if分⽀。降低程序耦合度。
2. 策略模式很少单独使⽤,⼀般结合⼯⼚模式、享元模式等。