1. 程式人生 > >C#設計模式之八橋接模式(Bridge)【結構型】

C#設計模式之八橋接模式(Bridge)【結構型】

升級 方向 implement 詳細 .cn mage names 這樣的 意圖

一、引言

今天我們要講【結構型】設計模式的第二個模式,該模式是【橋接模式】,也有叫【橋模式】的。大家第一次看到這個名稱會想到什麽呢?我第一次看到這個模式根據名稱猜肯定是連接什麽東西的。因為橋在我們現實生活中經常是連接著A地和B地,再往後來發展,橋引申為一種紐帶,比如:絲綢之路是連接亞洲和歐洲的橋梁。有了橋,我們出行方便了,從一個地方到另一個地方在有橋的情況更方便了(此處不許擡杠,當然是需要橋的情況)。橋是針對橋的使用環境來說的,解決了跨越和銜接的問題。在設計模式中的【橋模式】也有類似的概念,是連接了兩個不同維度的東西,而且這兩個維度又有強烈的變化,什麽叫強烈呢,經常變化,什麽是經常呢?哈哈,自己理解吧。


二、橋接模式的詳細介紹

2.1、動機(Motivate)

在很多遊戲場景中,會有這樣的情況:【裝備】本身會有的自己固有的邏輯,比如槍支,會有型號的問題,同時現在很多的遊戲又在不同的介質平臺上運行和使用,這樣就使得遊戲的【裝備】具有了兩個變化的維度——一個變化的維度為“平臺的變化”,另一個變化的維度為“型號的變化”。如果我們要寫代碼實現這款遊戲,難道我們針對每種平臺都實現一套獨立的【裝備】嗎?復用在哪裏?如何應對這種“多維度的變化”?如何利用面向對象技術來使得【裝備】可以輕松地沿著“平臺”和“型號”兩個方向變化,而不引入額外的復雜度?

2.2、意圖(Intent)

將抽象部分與實現部分分離,使它們都可以獨立地變化。

橋模式不能只是認為是抽象和實現的分離,它其實並不僅限於此。其實兩個都是抽象的部分,更確切的理解,應該是將一個事物中多個維度的變化分離

2.3、結構圖

技術分享

2.4、模式的組成

橋接模式的結構包括Abstraction、RefinedAbstraction、Implementor、ConcreteImplementorA和ConcreteImplementorB五個部分,其中:

  . Abstraction:定義抽象類的接口,它維護了一個指向Implementor類型對象的指針。

  . RefinedAbstraction:擴充由Abstraction定義的接口;

  . Implementor:定義實現類的接口,該接口不一定要與Abstraction的接口完全一致,事實上兩個接口可以完全不同。一般情況,Implementor接口僅為提供基本操作,而Abstraction則定義了基於基本操作的較高層次操作。

  . ConcreteImplementorA和ConcreteImplementorB:實現Implementor接口並定義它的具體實現。

  在橋接模式中,兩個類Abstraction和Implementor分別定義了抽象與行為類型的接口,通過調用兩接口的子類實現抽象與行為的動態組合。

2.5 、橋接模式的具體實現

今天我們就以數據庫為例來寫該模式的實現。每種數據庫都有自己的版本,但是每種數據庫在不同的平臺上實現又是不一樣的。比如:微軟的SqlServer數據庫,該數據庫它有2000版本、2005版本、2006版本、2008版本,後面還會有更新的版本。並且這些版本都是運行在Windows操作系統下的,如果要提供Lunix操作系統下的SqlServer怎麽辦呢?如果又要提供IOS操作系統下的SqlServer數據庫該怎麽辦呢?這個情況就可以使用橋接模式,也就是Brige模式。我們就來看看具體的實現吧!

 1 namespace 橋接模式的實現
 2 {
 3     /// <summary>
 4     /// 該抽象類就是抽象接口的定義,該類型就相當於是Abstraction類型
 5     /// </summary>
 6     public abstract class Database
 7     {
 8         //通過組合方式引用平臺接口,此處就是橋梁,該類型相當於Implementor類型
 9         private PlatformImplementor _implementor;
10 
11         //通過構造器註入,初始化平臺實現
12         protected Database(PlatformImplementor implementor)
13         {
14            this.__implementor=implementor;
15         }
16 
17         //創建數據庫--該操作相當於Abstraction類型的Operation方法
18         public abstract void Create();
19     }
20 
21     /// <summary>
22     /// 該抽象類就是實現接口的定義,該類型就相當於是Implementor類型
23     /// </summary>
24     public abstract class PlatformImplementor
25     {
26        //該方法就相當於Implementor類型的OperationImpl方法
27        public abstract void Process();
28     }
29  
30     /// <summary>
31     /// SqlServer2000版本的數據庫,相當於RefinedAbstraction類型
32     /// </summary>
33     public class SqlServer2000:Database
34     {
35         public override void Create()
36         {
37             this._implementor.Process();
38         }
39     }
40  
41     /// <summary>
42     /// SqlServer2005版本的數據庫,相當於RefinedAbstraction類型
43     /// </summary>
44     public class SqlServer2005:Database
45     {
46         public override void Create()
47         {
48             this._implementor.Process();
49         }
50     }
51 
52    /// <summary>
53     /// SqlServer2000版本的數據庫針對Unix操作系統具體的實現,相當於ConcreteImplementorA類型
54     /// </summary>
55     public class SqlServer2000UnixImplementor:PlatformImplementor
56     {
57         public override void Process()
58         {
59             //SqlServer2000針對Unix的具體實現;
60         }
61     }
62  
63     /// <summary>
64     /// SqlServer2005版本的數據庫針對Unix操作系統的具體實現,相當於ConcreteImplementorB類型
65     /// </summary>
66     public sealed class SqlServer2005UnixImplementor:PlatformImplementor
67     {
68         public override void Process()
69         {
70             //SqlServer2005針對Unix的具體實現;
71         }
72     }
73 
74    public class Program
75    {
76       static void Main()
77       {
78          PlatformImplementor SqlServer2000UnixImp=new SqlServer2000UnixImplementor();
79          //還可以針對不同平臺進行擴展,也就是子類化,這個是獨立變化的
80 
81          Database SqlServer2000Unix=new SqlServer2000(SqlServer2000UnixImp);
82          //數據庫版本也可以進行擴展和升級,也進行獨立的變化。
83 
84          以上就是兩個維度的變化。
85 
86          //就可以針對Unix執行操作了
87          SqlServer2000Unix.Create();
88       }
89    }
90 }

代碼都很簡單,也有詳細的備註,就不多說了。

三、橋接模式的實現要點:

1.Bridge模式使用“對象間的組合關系”解耦了抽象和實現之間固有的綁定關系,使得抽象和實現可以沿著各自的維度來變化。

2.所謂抽象和實現沿著各自維度的變化,即“子類化”它們,得到各個子類之後,便可以任意組合它們,從而獲得不同平臺上的不同型號。

3.Bridge模式有時候類似於多繼承方案,但是多繼承方案往往違背了類的單一職責原則(即一個類只有一個變化的原因),復用性比較差。Bridge模式是比多繼承方案更好的解決方法。

4.Bridge模式的應用一般在“兩個非常強的變化維度”,有時候即使有兩個變化的維度,但是某個方向的變化維度並不劇烈——換言之兩個變化不會導致縱橫交錯的結果,並不一定要使用Bridge模式。

四、.NET 中橋接模式的實現

學習中。。。,如果誰有好的代碼分享,也可以貼出來。

五、總結

今天的文章就寫到這裏了,現在小結一下。橋接模式它是連接客戶端代碼和具體實現代碼的一座橋梁,同時它也隔離了實現代碼的改變對客戶代碼的影響。在【意圖】中所說的抽象和實現,這兩個部分其實都是高度抽象的,前面“抽象”是指定義的針對客戶端的接口,客戶端其實使用的是Abstract類型或者是RefinedAbstract類型,這兩個類型只是接口,具體的實現委托給了Implementor類型了,Abstract類型子類化的擴展也演變成Implementor子類化的變化。我個人的理解,Abstract類型和其子類型在客戶端代碼和真正實現的代碼之間起到了橋梁的作用,隔離了Implementor實現代碼的變化,讓客戶端更穩定,所以【意圖】才說是講抽象部分和它的實現部分隔離。大家好好理解一下吧,剛開始有點繞。

C#設計模式之八橋接模式(Bridge)【結構型】