策略模式使用总结

策略模式总结#

一、前言#

在写代码的过程中,难免会遇到switch语句,2-3case的时候倒是无所谓,如果多了,例如要写7-8个的时候,难免就会让人头疼呀.虽然switch语句是目前为止简单且最有效的方式,但是难免让人看了比较惆怅.这个时候就需要代码优化,提高扩展性.

二、示例#

看一段相识的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CountType type = DataDto.getCountType();
switch(type){
case CountType.MOBILE:
//do something
break;
case CountType.WEB:
//do something
break;
case CountType.OTHER:
//do something
break;
//......
// |
// |
//......
}

看着还好,分支不是特别的多,如果分支特别多那就灾难了.

三、优化#

简单优化代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Map<CountType,Handler> map = new HashMap<CountType,Handler>(){{
put(CountType.MOBILE,()->{
//do something
});
put(CountType.WEB,()->{
//do something
});
put(CountType.OTHER,()->{
//do something
})
//..........
// |
// |
//.........

}};
//获取类型
CountType type = DataDto.getType();
//获取类型,执行响应的逻辑代码
map.get(type).exec();

@FunctionalInterface
public interface Handler{

void exec();

}

emmmmmmm 貌似这样可以简化一些,但是还是有局限性,这种方式把处理的逻辑放在一个类里面,让后做代码自动路由,看起不错,却缺乏扩展性,不灵活.如果其他类也有类似的逻辑怎么办?copy一份过去嘛??不,这样就违反了面向对象的原则.我们需要一种更加灵活,可扩展性,面向对象的方案.

四、策略模式#

何为策略模式,策略模式是属于设计模式中的一种.在策略模式中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

  • 优点
    1. 算法可以自由切换
    2. 避免使用多重条件判断
    3. 扩展性良好
  • 缺点
    1. 策略类会增多,策略膨胀
    2. 所有策略类都需要对外暴露
  • 解决痛点
    1. 冗长的if else or switch
    2. 动态的选择算法

针对上面的代码,使用策略模式进行优化一下吧.代码如下

1
2
3
4
//创建策略接口
public interface Strategy{
void exec();
}
1
2
3
4
5
6
7
8
//创建mobile处理策略
public class MobileStrategy implements Strategy{

public void exec(){
System.out.print("MobileStrategy exec....");
}

}
1
2
3
4
5
6
//创建Web处理策略
public class WebStrategy implements Strategy{
public void exec(){
System.out.print("WebStrategy exec...");
}
}
1
2
3
4
5
6
//创建other处理策略
public class OtherStrategy implements Strategy{
public void exec(){
System.out.print("OtherStrategy exec...");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//创建策略上下文
public class HandlerContext{

private final Map<CountType,Strategy> map = new HashMap<CountType,Strategy>(){{
put(CountType.MOBILE,new MobileStrategy());
put(CountType.WEB,new WebStrategy());
put(CountType.OTHER,new OtherStrategy());
}};

public void execStrategy(CountType type){
//执行策略
map.get(type).exec();
}
}
1
2
3
4
5
6
7
8
public class Main{

public void main(String[] args){
CountType type = DataDto.getType();
HandlerContext context = new HandlerContext();
context.execStrategy(type);
}
}

如上代码就算利用策略模式进行的优化,即实现了代码自动路由,又充满扩展性.策略模式还可以利用享元模式进行优化,这样避免策略较多而产生的内存的开销.但策略膨胀这个是无法避免的.

总结#

设计模式只有使用的时候,才会认识的彻底.

感谢您的阅读,本文由 Onew 版权所有。如若转载,请注明出处:Onew(https://onew.me/2018/04/20/strategy-pattern/
RxJava学习笔记(一)
尝鲜 Mysql 8.0的初体验