橋接模式-1

在網上看到一篇很不錯的文章,想轉載下來建立資料庫,共同學習,一起分享。----Noted by me

轉載於:http://chjavach.iteye.com/blog/738056          http://blog.csdn.net/ljianhui


   

 

 

橋接模式(Bridge)

1  場景問題

1.1  發送提示消息

        考慮這樣一個實際的業務功能:發送提示消息。基本上所有帶業務流程處理的系統都會有這樣的功能,比如某人有新的工作了,需要發送一條消息提示他。
        從業務上看,消息又分成普通消息、加急消息和特急消息多種,不同的消息類型,業務功能處理是不一樣的,比如加急消息是在消息上添加加急,而特急消息除了添加特急外,還會做一條催促的記錄,多久不完成會繼續催促。從發送消息的手段上看,又有系統內短消息、手機短消息、郵件等等。
        現在要實現這樣的發送提示消息的功能,該如何實現呢?


1.2  不用模式的解決方案

1:實現簡化版本
        先考慮實現一個簡單點的版本,比如:消息先只是實現發送普通消息,發送的方式呢,先實現系統內短消息和郵件。其它的功能,等這個版本完成過後,再繼續添加,這樣先把問題簡單化,實現起來會容易一點。
 (1)由於發送普通消息會有兩種不同的實現方式,爲了讓外部能統一操作,因此,把消息設計成接口,然後由兩個不同的實現類,分別實現系統內短消息方式和郵件發送消息的方式。此時系統結構如圖1所示:

 

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

 

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

(2)先來看看消息的統一接口,示例代碼如下:

Java代碼  收藏代碼
  1. /** 
  2.  * 消息的統一接口 
  3.  */  
  4. public interface Message {  
  5.     /** 
  6.      * 發送消息 
  7.      * @param message 要發送的消息內容 
  8.      * @param toUser 消息發送的目的人員 
  9.      */  
  10.     public void send(String message,String toUser);  
  11. }  

 

 (3)再來分別看看兩種實現方式,這裏只是爲了示意,並不會真的去發送Email和站內短消息,先看站內短消息的方式,示例代碼如下:

Java代碼  收藏代碼
  1. /** 
  2.  * 以站內短消息的方式發送普通消息 
  3.  */  
  4. public  class CommonMessageSMS implements Message{  
  5.     public void send(String message, String toUser) {  
  6.         System.out.println("使用站內短消息的方式,發送消息'"  
  7. +message+"'給"+toUser);  
  8.     }  
  9. }  

  

同樣的,實現以Email的方式發送普通消息,示例代碼如下:

Java代碼  收藏代碼
  1. /** 
  2.  * 以Email的方式發送普通消息 
  3.  */  
  4. public class CommonMessageEmail implements Message{  
  5.     public void send(String message, String toUser) {  
  6.         System.out.println("使用Email的方式,發送消息'"  
  7. +message+"'給"+toUser);  
  8.     }  
  9. }  

  

2:實現發送加急消息


        上面的實現,看起來很簡單,對不對。接下來,添加發送加急消息的功能,也有兩種發送的方式,同樣是站內短消息和Email的方式。
        加急消息的實現跟普通消息不同,加急消息會自動在消息上添加加急,然後再發送消息;另外加急消息會提供監控的方法,讓客戶端可以隨時通過這個方法來了解對於加急消息處理的進度,比如:相應的人員是否接收到這個信息,相應的工作是否已經開展等等。因此加急消息需要擴展出一個新的接口,除了基本的發送消息的功能,還需要添加監控的功能,這個時候,系統的結構如圖2所示:
 

 

 

                                      圖2  加入發送加急消息後的系統結構示意圖

(1)先看看擴展出來的加急消息的接口,示例代碼如下:

 

Java代碼  收藏代碼
  1. /** 
  2.  * 加急消息的抽象接口 
  3.  */  
  4. public interface UrgencyMessage extends Message{  
  5.     /** 
  6.      * 監控某消息的處理過程 
  7.      * @param messageId 被監控的消息的編號 
  8.      * @return 包含監控到的數據對象,這裏示意一下,所以用了Object 
  9.      */  
  10.     public Object watch(String messageId);  
  11. }  

 

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

Java代碼  收藏代碼
  1. public class UrgencyMessageSMS implements UrgencyMessage{  
  2.     public void send(String message, String toUser) {  
  3.         message = "加急:"+message;  
  4.         System.out.println("使用站內短消息的方式,發送消息'"  
  5. +message+"'給"+toUser);  
  6.     }  
  7.   
  8.     public Object watch(String messageId) {  
  9.         //獲取相應的數據,組織成監控的數據對象,然後返回         
  10.         return null;  
  11.     }     
  12. }  

 

 再看看Emai的方式,示例代碼如下:

Java代碼  收藏代碼
  1. public class UrgencyMessageEmail implements UrgencyMessage{  
  2.     public void send(String message, String toUser) {  
  3.         message = "加急:"+message;  
  4.         System.out.println("使用Email的方式,發送消息'"  
  5. +message+"'給"+toUser);  
  6.     }  
  7.     public Object watch(String messageId) {  
  8.         //獲取相應的數據,組織成監控的數據對象,然後返回         
  9.         return null;  
  10.     }     
  11. }  

 

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


1.3  有何問題

        上面這樣實現,好像也能滿足基本的功能要求,可是這麼實現好不好呢?有沒有什麼問題呢?
        咱們繼續向下來添加功能實現,爲了簡潔,就不再去進行代碼示意了,通過實現的結構示意圖就可以看出實現上的問題。
1:繼續添加特急消息的處理
        特急消息不需要查看處理進程,只要沒有完成,就直接催促,也就是說,對於特急消息,在普通消息的處理基礎上,需要添加催促的功能。而特急消息、還有催促的發送方式,相應的實現方式還是發送站內短消息和Email兩種,此時系統的結構如圖3所示:



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

        仔細觀察上面的系統結構示意圖,會發現一個很明顯的問題,那就是:通過這種繼承的方式來擴展消息處理,會非常不方便。
        你看,實現加急消息處理的時候,必須實現站內短消息和Email兩種處理方式,因爲業務處理可能不同;在實現特急消息處理的時候,又必須實現站內短消息和Email這兩種處理方式。
        這意味着,以後每次擴展一下消息處理,都必須要實現這兩種處理方式,是不是很痛苦,這還不算完,如果要添加新的實現方式呢?繼續向下看吧。


2:繼續添加發送手機消息的處理方式

        如果看到上面的實現,你還感覺問題不是很大的話,繼續完成功能,添加發送手機消息的處理方式。
        仔細觀察現在的實現,如果要添加一種新的發送消息的方式,是需要在每一種抽象的具體實現裏面,都要添加發送手機消息的處理的。也就是說:發送普通消息、加急消息和特急消息的處理,都可以通過手機來發送。這就意味着,需要添加三個實現。此時系統結構如圖4所示:
 

 

                                圖4  加入發送手機消息後的系統結構示意圖
        這下能體會到這種實現方式的大問題了吧。


3:小結一下出現的問題
        採用通過繼承來擴展的實現方式,有個明顯的缺點:擴展消息的種類不太容易,不同種類的消息具有不同的業務,也就是有不同的實現,在這種情況下,每個種類的消息,需要實現所有不同的消息發送方式。
        更可怕的是,如果要新加入一種消息的發送方式,那麼會要求所有的消息種類,都要加入這種新的發送方式的實現。
要是考慮業務功能上再擴展一下呢?比如:要求實現羣發消息,也就是一次可以發送多條消息,這就意味着很多地方都得修改,太恐怖了。
        那麼究竟該如何實現才能既實現功能,又能靈活的擴展呢?


========待續見2========

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章