重構 - 觀察者模式

self_blank發表於2018-05-30

在一個實現通知功能的介面中,通常用一個通知型別notifyType來區別不同的業務場景,然後用switch來劃分不同的邏輯流向。

String notifyType = "";
switch (notifyType) {
    case "型別1":
        doType1();  // 邏輯1
        break;
    case "型別2":
        doType2();  // 邏輯2
        break;
}複製程式碼

但這樣擴充套件性不好,當新增一個通知型別(eg:型別3),則需要修改switch方法,違背了開放封閉原則。這時可以用觀察者模式來進行改造。


觀察者模式原理在此不再做闡述,具體實現如下:

1. 定義一個抽象的通知監聽器介面

public interface NotifyReqListener {
    /** 具體執行函式 **/
    boolean action(NotifyReq notifyReq);
}
複製程式碼


2. 定義一個監聽者註冊類

@Component
public class NotifyReqListenerRegistry {
  
    // 建立通知型別與監聽器之間的對映關係
    private Map<String, NotifyReqListener> listenerMap = new ConcurrentHashMap<String, NotifyReqListener>();

    // 新增監聽器
    public void addListener(String notifyType, NotifyReqListener listener) {
        if (listener != null && notifyType != null) {
            listenerMap.put(notifyType, listener);
	}
    }

    // 通過通知型別獲取指定的監聽器
    public NotifyReqListener getListener(String notifyType) {
        return listenerMap.get(notifyType);
    }
}複製程式碼


3. 當新增一個通知型別時,只要往監聽器註冊即可。

NotifyReqListener listener = notifyReqListenerRegistry.getListener(notifyReq.getNotifyType());
if (listener != null) {
    res = listener.action(notifyReq);
} else {
    logger.error("getNotifyType invalid {}", notifyReq);
}複製程式碼


4. 假設現在新增一個通知型別newType

String newNotifyType = "newType";複製程式碼

只需建立一個監聽類,實現NotifyReqListener介面,然後重寫action,實現自己的業務邏輯。

@Component
public class NewTypeListener implements NotifyReqListener {

    private NotifyReqListenerRegistry registry;    

    @Override
    public boolean action(NotifyReq notifyReq) {
        // 重寫action,實現newType的業務邏輯  }

  public NotifyReqListenerRegistry getRegistry() {
        return registry;
  }

  @Autowired
  public void setRegistry(NotifyReqListenerRegistry registry) {
        this.registry = registry;
        // 將新的通知型別註冊到監聽器
	registry.addListener("newType", this);
  }
}複製程式碼


相關文章