基於注解實現的策略模式,步驟簡單,通俗易懂!


背景

在項目開發的過程中,我們經常會遇到如下的一種場景:對於用戶的請求需要根據不同的情況進行不同的處理。

  • 最簡單粗暴的一種處理方式是使用switch…case或者if…else。但是這樣處理方式只適用於處理邏輯簡單或者情況分類較少的情況,如學校發放校服,男同學發放男士衣服,女同學發放女士衣服。
  • 但是,如果處理邏輯畢竟復雜,或者情況分類較多,甚至未來有可能增加情況分類,上一種處理方式就會顯得力不從心。此時使用策略模式將會是一種更優的處理方式。

基礎配置&步驟

以下的方案是基於注解實現的策略模式。基礎步驟&配置如下:

  • 定義策略名稱:該項使用枚舉實現
  • 定義策略名稱注解:使用注解進行定義
  • 定義策略行為接口:該接口定義了策略行為
  • 定義策略處理器:包含策略名稱的注解,並實現了策略行為接口
  • 定義策略容器:此處使用map作為策略容器,key為策略名稱注解,value為策略處理器的實例
  • 初始化策略:容器初始化時候,從容器中讀取包含策略名稱注解的實例,並將其放入到策略容器中。

代碼實現

在以下的例子中,會針對用戶請求的Msg進行解析,msgType有兩種:一種是聊天消息ChatMsg,還有一種是系統消息SysMsg。實現方式如下所示:

定義策略名稱

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());
        });
    }
}

上述准備動作完成后,就可以編寫調用代碼了:

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核心知識點總結!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM