研磨設計模式之橋接模式 1

2021-08-25 09:14:21 字數 3213 閱讀 9547

來寫乙個大家既陌生又熟悉的設計模式,也是非常實用的乙個設計模式,那就是橋接模式。

說陌生是很多朋友並不熟悉這個設計模式,說熟悉是很多人經常見到或者是下意識的用到這個設計模式,只是不知道罷了。橋接模式是非常實用的乙個模式,下面就來寫寫它。

考慮這樣乙個實際的業務功能:傳送提示訊息。基本上所有帶業務流程處理的系統都會有這樣的功能,比如某人有新的工作了,需要傳送一條訊息提示他。

從業務上看,訊息又分成普通資訊、加急訊息和特急訊息多種,不同的訊息型別,業務功能處理是不一樣的,比如加急訊息是在訊息上新增加急,而特急訊息除了新增特急外,還會做一條催促的記錄,多久不完成會繼續催促。從傳送訊息的手段上看,又有系統內短訊息、手機短訊息、郵件等等。

現在要實現這樣的傳送提示訊息的功能,該如何實現呢?

1:實現簡化版本

先考慮實現乙個簡單點的版本,比如:訊息先只是實現傳送普通資訊,傳送的方式呢,先實現系統內短訊息和郵件。其它的功能,等這個版本完成過後,再繼續新增,這樣先把問題簡單化,實現起來會容易一點。

(1)由於傳送普通資訊會有兩種不同的實現方式,為了讓外部能統一操作,因此,把訊息設計成介面,然後由兩個不同的實現類,分別實現系統內短訊息方式和郵件傳送訊息的方式。此時系統結構如圖1所示:

圖1  簡化版本的系統結構示意圖

下面看看大致的實現示意。

(2)先來看看訊息的統一介面,示例**如下:

/**

* 訊息的統一介面

*/public inte***ce message

(3)再來分別看看兩種實現方式,這裡只是為了示意,並不會真的去傳送email和站內短訊息,先看站內短訊息的方式,示例**如下:

/**

* 以站內短訊息的方式傳送普通資訊

*/public class commonmessagesms implements message

}

同樣的,實現以email的方式傳送普通資訊,示例**如下:

/**

* 以email的方式傳送普通資訊

*/public class commonmessageemail implements message

}

2:實現傳送加急訊息上面的實現,看起來很簡單,對不對。接下來,新增傳送加急訊息的功能,也有兩種傳送的方式,同樣是站內短訊息和email的方式。

加急訊息的實現跟普通資訊不同,加急訊息會自動在訊息上新增加急,然後再傳送訊息;另外加急訊息會提供監控的方法,讓客戶端可以隨時通過這個方法來了解對於加急訊息處理的進度,比如:相應的人員是否接收到這個資訊,相應的工作是否已經開展等等。因此加急訊息需要擴充套件出乙個新的介面,除了基本的傳送訊息的功能,還需要新增監控的功能,這個時候,系統的結構如圖2所示:

圖2  加入傳送加急訊息後的系統結構示意圖

(1)先看看擴充套件出來的加急訊息的介面,示例**如下:

/**

* 加急訊息的抽象介面

*/public inte***ce urgencymessage extends message

(2)相應的實現方式還是傳送站內短訊息和email兩種,同樣需要兩個實現類來分別實現這兩種方式,先看站內短訊息的方式,示例**如下:

public class urgencymessagesms implements urgencymessage

public object watch(string messageid)

}

再看看emai的方式,示例**如下:

public class urgencymessageemail implements urgencymessage

public object watch(string messageid)

}

(3)事實上,在實現加急訊息傳送的功能上,可能會使用前面傳送不同訊息的功能,也就是讓實現加急訊息處理的物件繼承普通資訊的相應實現,這裡為了讓結構簡單一點,清晰一點,所以沒有這樣做。

上面這樣實現,好像也能滿足基本的功能要求,可是這麼實現好不好呢?有沒有什麼問題呢?

咱們繼續向下來新增功能實現,為了簡潔,就不再去進行**示意了,通過實現的結構示意圖就可以看出實現上的問題。

1:繼續新增特急訊息的處理

特急訊息不需要檢視處理程序,只要沒有完成,就直接催促,也就是說,對於特急訊息,在普通資訊的處理基礎上,需要新增催促的功能。而特急訊息、還有催促的傳送方式,相應的實現方式還是傳送站內短訊息和email兩種,此時系統的結構如圖3所示:

圖3  加入傳送特急訊息後的系統結構示意圖

仔細觀察上面的系統結構示意圖,會發現乙個很明顯的問題,那就是:通過這種繼承的方式來擴充套件訊息處理,會非常不方便。

你看,實現加急訊息處理的時候,必須實現站內短訊息和email兩種處理方式,因為業務處理可能不同;在實現特急訊息處理的時候,又必須實現站內短訊息和email這兩種處理方式。

這意味著,以後每次擴充套件一下訊息處理,都必須要實現這兩種處理方式,是不是很痛苦,這還不算完,如果要新增新的實現方式呢?繼續向下看吧。

2:繼續新增傳送手機訊息的處理方式

如果看到上面的實現,你還感覺問題不是很大的話,繼續完成功能,新增傳送手機訊息的處理方式。

仔細觀察現在的實現,如果要新增一種新的傳送訊息的方式,是需要在每一種抽象的具體實現裡面,都要新增傳送手機訊息的處理的。也就是說:傳送普通資訊、加急訊息和特急訊息的處理,都可以通過手機來傳送。這就意味著,需要新增三個實現。此時系統結構如圖4所示:

圖4  加入傳送手機訊息後的系統結構示意圖

這下能體會到這種實現方式的大問題了吧。

3:小結一下出現的問題

採用通過繼承來擴充套件的實現方式,有個明顯的缺點:擴充套件訊息的種類不太容易,不同種類的訊息具有不同的業務,也就是有不同的實現,在這種情況下,每個種類的訊息,需要實現所有不同的訊息傳送方式。

更可怕的是,如果要新加入一種訊息的傳送方式,那麼會要求所有的訊息種類,都要加入這種新的傳送方式的實現。

要是考慮業務功能上再擴充套件一下呢?比如:要求實現**訊息,也就是一次可以傳送多條訊息,這就意味著很多地方都得修改,太恐怖了。

那麼究竟該如何實現才能既實現功能,又能靈活的擴充套件呢?

也可以直接在卓越網上搜尋《研磨設計模式》

*****===未完待續*****===

設計模式之橋接模式

public class test 兩個維度 乙個是具體產品,如狗 豬 乙個是抽象產品,如溫順的動物 冷酷的動物 排列組合 如溫順的狗 冷酷的豬等 abstract class animal 該橋接類的引入是關鍵 abstract class animalbridge extends animal ...

設計模式之 橋接模式

今天來學習橋接模式,在我們日常生活中,有很多的事物是可以 多維度 的變化的,比如我們去吃麵條,有雞絲面和牛肉麵兩種,每一種面又分為辣味的和不辣的,而且每種面可能會分為大碗小碗的。很多事物能夠變化的維度不止一種,甚至數十種,那麼我們在 上怎麼應對這些變化呢?每乙個都單獨弄乙個類顯然不是什麼好辦法。那麼...

設計模式之橋接模式

在軟體系統中,某些型別由於自身的邏輯,它具有兩個或多個維度的變化,那麼如何應對這種 多維度的變化 如何利用物件導向的技術來使得該型別能夠輕鬆的沿著多個方向進行變化,而又不引入額外的複雜度?這就要使用橋接模式。現在有咖啡,按大小分可以分為中杯和大杯,按型別可以分為拿鐵和摩卡,所以現在總共有四中咖啡,中...