使用橋接模式設計複雜訊息系統

2020-10-13 01:00:26
對於什麼時候使用橋接模式,大家可能還不是很清楚。舉個例子,我們平時工作時經常需要通過郵件訊息、簡訊訊息或者系統內訊息與同事溝通。尤其在走一些審批流程的時候,需要記錄這些過程以詳細調查。

根據型別劃分,訊息可以分為郵件訊息、簡訊訊息和系統內訊息。但是,根據緊急程度來劃分,訊息可以分為普通訊息、加急訊息和特急訊息。顯然,整個訊息系統可以劃分為兩個維度。

這種情況如果用繼承,實現就會比較複雜,而且也不利於擴充套件。比如,郵件訊息可以是普通的,也可以是加急的。同樣,簡訊訊息可以是普通的,也可以是加急的。

下面我們用橋接模式來解決這個問題。

首先建立 IMsg 介面擔任橋接的角色,程式碼如下:
/**
* 實現訊息傳送的統一介面
*/
public interface IMsg {
    // 要傳送的訊息的內容和接收人
    void send(String msg, String toUser);
}
建立郵件訊息 EmailMsg 類。
/**
* 郵件訊息的實現類
*/
public class EmailMsg implements IMsg {
    public void send(String msg, String toUser) {
        System.out.println("使用郵件訊息傳送" + msg + "給" + toUser);
    }
}
建立簡訊訊息 SmsMsg 類。
/**
* 簡訊訊息的實現類
*/
public class SmsMsg implements IMsg {
    public void send(String msg, String toUser) {
        System.out.println("使用簡訊訊息傳送" + msg + "給" + toUser);
    }
}
然後建立橋接角色 AbstractMsg 類。
/**
* 抽象訊息類
*/
public abstract class AbstractMsg {
    //持有一個實現部分的物件
    IMsg msg;

    //構造方法,傳入實現部分的物件
    public AbstractMsg(IMsg msg) {
        this.msg = msg;
    }

    //傳送訊息,委派給實現部分的方法
    public void sendMsg(String msg, String toUser) {
        this.msg.send(msg, toUser);
    }
}
建立具體普通訊息 NomalMsg 類。
/**
* 普通訊息類
*/
public class NomalMsg extends AbstractMsg {
    //構造方法,傳入實現部分的物件
    public NomalMsg(IMsg msg) {
        super(msg);
    }

    @Override
    public void sendMsg(String msg, String toUser) {
        //對於普通訊息,直接呼叫父類別方法傳送訊息即可
        super.sendMsg(msg, toUser);
    }
}
建立具體加急訊息 UrgencyMsg 類。
/**
* 加急訊息類
*/
public class UrgencyMsg extends AbstractMsg {
    //構造方法
    public UrgencyMsg(IMsg msg) {
        super(msg);
    }

    @Override
    public void sendMsg(String msg, String toUser) {
        msg = "【加急】" + msg;
        super.sendMsg(msg, toUser);
    }

    //擴充套件它功能,監控某個訊息的處理狀態
    public Object watch(String msgId) {
        //根據給出的訊息編碼(msgId)查詢訊息的處理狀態
        //組織成監控的處理狀態,然後返回
        return null;
    }
}
最後編寫使用者端測試程式碼。
public class Test {
    public static void main(String[] args) {
        IMsg msg = new SmsMsg();
        AbstractMsg abstractMsg = new NomalMsg(msg);
        abstractMsg.sendMsg("加班申請速批", "C語言中文網嚴總");

        Msg = new EmailMsg();
        abstractMsg = new UrgencyMsg(msg);
        abstractMsg.sendMsg("加班申請速批", "C語言中文網嚴總");
    }
}
執行結果如下所示。

使用簡訊訊息傳送加班申請速批給C語言中文網嚴總
使用郵件訊息傳送【加急】加班申請速批給C語言中文網嚴總

在上面的案例中,我們採用橋接模式解耦了“訊息型別”和“訊息緊急程度”這兩個獨立變化的維度。

後續如果有更多的訊息型別,比如微信、釘釘等,則直接新建一個類實現 IMsg 即可。如果緊急程度需要新增,則同樣只需新建一個類繼承 AbstractMsg 類即可。