什么时候用策略模式
在java的编码中,为了消除和避免大段的if else语句,我们常常会使用策略模式,来使得代码结构变得清晰可维护。
下面说一下我在写代码中的一个真实的例子,写的时候自己思考的,后来看《effective java》恰好验证了这个小技巧,还是蛮爽的。
问题背景
策略模式标准写法
- 定义一个策略接口
//Strategy.java
public interface Strategy {
void preProcessClient(xxx);
void preResponseAdsRefill(xxx);
}
- 处理依赖于接口,构造函数中传入实例化好的策略
//Process.java
public class Process {
//当前的处理方式
private Strategy strategy;
public Process(Strategy strategy) {
this.strategy = strategy;
}
public void preProcessClient(xxx) {
strategy.preProcessClient(xxx);
}
public void preResponseAdsRefill(xxx) {
strategy.preResponseAdsRefill(xxx);
}
}
- 实现接口
技巧
其实很多时候处理的策略都是一样的,没有必要每一次请求过来都new
一个Strategy
出来,所以在process 加一个“单例”进行管理即可,把策略的解析下移到Process中,因为我们通常需要根据某些参数确定是什么策略。
//Process.java
public class Process {
private static final Map<Key, Strategy> Key2Strategy = new EnumMap<>(Key.class);
static {
Key2Strategy.put(Key.A, new aStrategy());
Key2Strategy.put(Key.B, new bStrategy());
Key2Strategy.put(Key.C, new cStrategy());
Key2Strategy.put(Key.D, new dStrategy());
}
//当前的处理方式
private Strategy strategy;
public Process(xxx) {//xxx为可以确定策略的对象
//解析,
}
public Process(Strategy strategy) {
this.strategy = strategy;
}
public void preProcessClient(xxx) {
strategy.preProcessClient(xxx);
}
public void preResponseAdsRefill(xxx) {
strategy.preResponseAdsRefill(xxx);
}
}
思考
策略模式如果策略类太多怎么办,这个问题一直困扰我,但是轮子哥在知乎上的一个回答说的好:
你的业务逻辑这么复杂,不要妄图使用简单的代码就能解决问题。代码的复杂程度是直接跟你的需求呈正比的。