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 STRATEGY_MAP = new HashMap();

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. 策略模式很少单独使⽤,⼀般结合⼯⼚模式、享元模式等。