背景
在項目開發(fā)的過程中,我們經(jīng)常會遇到如下的一種場景:對于用戶的請求需要根據(jù)不同的情況進行不同的處理。
- 最簡單粗暴的一種處理方式是使用switch…case或者if…else。但是這樣處理方式只適用于處理邏輯簡單或者情況分類較少的情況,如學校發(fā)放校服,男同學發(fā)放男士衣服,女同學發(fā)放女士衣服。
- 但是,如果處理邏輯畢竟復雜,或者情況分類較多,甚至未來有可能增加情況分類,上一種處理方式就會顯得力不從心。此時使用策略模式將會是一種更優(yōu)的處理方式。
基礎配置&步驟
以下的方案是基于注解實現(xiàn)的策略模式。基礎步驟&配置如下:
- 定義策略名稱:該項使用枚舉實現(xiàn)
- 定義策略名稱注解:使用注解進行定義
- 定義策略行為接口:該接口定義了策略行為
- 定義策略處理器:包含策略名稱的注解,并實現(xiàn)了策略行為接口
- 定義策略容器:此處使用map作為策略容器,key為策略名稱注解,value為策略處理器的實例
- 初始化策略:容器初始化時候,從容器中讀取包含策略名稱注解的實例,并將其放入到策略容器中。
代碼實現(xiàn)
在以下的例子中,會針對用戶請求的Msg進行解析,msgType有兩種:一種是聊天消息ChatMsg,還有一種是系統(tǒng)消息SysMsg。實現(xiàn)方式如下所示:
定義策略名稱
public enum MsgType {
CHAT_MSG,
SYS_MSG;
}
定義策略名稱注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Type {
MsgType value();
}
定義策略行為接口
public interface BaseMsgHandler {
void handleMsg(String content);
}
定義策略處理器
@Component
@Type(value = MsgType.CHAT_MSG)
public class ChatMsgHandler implements BaseMsgHandler{
@Override
public void handleMsg(String msg) {
System.out.println("This is chatMsg. Detail msg information is :" + msg);
}
}
@Component
@Type(value = MsgType.SYS_MSG)
public class SysMsgHandler implements BaseMsgHandler{
@Override
public void handleMsg(String msg) {
System.out.println("This is sysMsg. Detail msg information is :" + msg);
}
}
定義策略容器
public static final Map<Type, BaseMsgHandler> msgStrategyMap = new HashMap<>();
初始化策略
@Component
public class MsgConfig implements ApplicationContextAware {
public static final Map<Type, BaseMsgHandler> msgStrategyMap = new HashMap<>();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
applicationContext.getBeansWithAnnotation(Type.class).entrySet().iterator().forEachRemaining(entrySet ->{
msgStrategyMap.put(entrySet.getKey().getClass().getAnnotation(Type.class),
(BaseMsgHandler) entrySet.getValue());
});
}
}
上述準備動作完成后,就可以編寫調(diào)用代碼了:
import lombok.Data;
@Data
public class Msg{
private String content;
private MsgType msgType;
}
@RestController
@RequestMapping("/")
public class MsgController {
@RequestMapping("msg")
public void handleMsg(@RequestBody Msg msg){
BaseMsgHandler handler = MsgConfig.msgStrategyMap.get(msg.getMsgType());
handler.handleMsg(msg.getContent());
}
}
最后
歡迎關注公眾號:前程有光,領取一線大廠Java面試題總結+各知識點學習思維導+一份300頁pdf文檔的Java核心知識點總結!