|
原網(wǎng)址:http://www.cnblogs.com/libingql/p/3496075.html 1、橋接模式簡介 1.1>、定義 當(dāng)一個抽象可能有多個實(shí)現(xiàn)時,通常用繼承來進(jìn)行協(xié)調(diào)。抽象類定義對該抽象的接口,而具體的子類則用不同的方式加以實(shí)現(xiàn)。繼承機(jī)制將抽象部分與它的實(shí)現(xiàn)部分固定在一起,使得難以對抽象部分和實(shí)現(xiàn)部分獨(dú)立地進(jìn)行修改、擴(kuò)充和重用。 如果一個抽象類或接口有多個具體實(shí)現(xiàn)子類,而這些子類之中有內(nèi)容或概念上重疊,需要我們把抽象的共同部分各自獨(dú)立開來:即原來是準(zhǔn)備放在一個接口里,現(xiàn)在需要設(shè)計兩個接口——抽象接口和行為接口。然后再分別針對各自的具體子類定義抽象接口和行為接口的方法和調(diào)用關(guān)系。
橋接模式的用意是將抽象化(Abstraction)與實(shí)現(xiàn)化(Implementation)脫耦,使得二者可以獨(dú)立地變化。 抽象化(Abstraction) 實(shí)現(xiàn)化(Implementation) 抽象化給出的具體實(shí)現(xiàn),即為實(shí)現(xiàn)化。 脫耦 1.2>、使用頻率 2、橋接模式結(jié)構(gòu)圖
橋接模式的結(jié)構(gòu)包括Abstraction、RefinedAbstraction、Implementor、ConcreteImplementorA和ConcreteImplementorB五個部分,其中: Abstraction:定義抽象類的接口,它維護(hù)了一個指向Implementor類型對象的指針。 RefinedAbstraction:擴(kuò)充由Abstraction定義的接口; Implementor:定義實(shí)現(xiàn)類的接口,該接口不一定要與Abstraction的接口完全一致,事實(shí)上兩個接口可以完全不同。一般情況,Implementor接口僅為提供基本操作,而Abstraction則定義了基于基本操作的較高層次操作。 ConcreteImplementorA和ConcreteImplementorB:實(shí)現(xiàn)Implementor接口并定義它的具體實(shí)現(xiàn)。 在橋接模式中,兩個類Abstraction和Implementor分別定義了抽象與行為類型的接口,通過調(diào)用兩接口的子類實(shí)現(xiàn)抽象與行為的動態(tài)組合。 3、橋接模式結(jié)構(gòu)實(shí)現(xiàn)
Implementor.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Structural { public abstract class Implementor { public abstract void Operation(); } } Abstraction.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Structural { public class Abstraction { protected Implementor implementor; public Implementor Implementor { set { implementor = value; } } public virtual void Operation() { implementor.Operation(); } } } ConcreteImplementorA.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Structural { public class ConcreteImplementorA : Implementor { public override void Operation() { Console.WriteLine("ConcreteImplementorA Operation"); } } } ConcreteImplementorB.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Structural { public class ConcreteImplementorB : Implementor { public override void Operation() { Console.WriteLine("ConcreteImplementorB Operation"); } } } RefinedAbstraction.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Structural { public class RefinedAbstraction : Abstraction { public override void Operation() { implementor.Operation(); } } } Client.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Structural { public class Client { static void Main(string[] args) { Abstraction abstraction = new RefinedAbstraction(); abstraction.Implementor = new ConcreteImplementorA(); abstraction.Operation(); abstraction.Implementor = new ConcreteImplementorB(); abstraction.Operation(); } } } 運(yùn)行結(jié)果: ConcreteImplementorA Operation ConcreteImplementorB Operation 請按任意鍵繼續(xù). . . 4、橋接模式實(shí)際應(yīng)用 以一杯咖啡為例,子類有四個:中杯加奶、大杯加奶、中杯不加奶、大杯不加奶。這四個類實(shí)際是兩個角色的組合:抽象和行為。其中抽象為中杯和大杯,行為為加奶和不加奶。這種從分離抽象和行為的角度的方法稱為橋接模式。
MakeCoffee.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Practical { public abstract class MakeCoffee { public abstract void Making(); } } MakeCoffeeSingleton.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Practical { /// <summary> /// 單件模式類用來加載當(dāng)前MakeCoffee /// </summary> public sealed class MakeCoffeeSingleton { private static MakeCoffee _instance; public MakeCoffeeSingleton(MakeCoffee instance) { _instance = instance; } public static MakeCoffee Instance() { return _instance; } } } Coffee.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Practical { public abstract class Coffee { private MakeCoffee _makeCoffee; public Coffee() { _makeCoffee = MakeCoffeeSingleton.Instance(); } public MakeCoffee MakeCoffee() { return this._makeCoffee; } public abstract void Make(); } } BlackCoffee.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Practical { /// <summary> /// 原味咖啡 /// </summary> public class BlackCoffee : MakeCoffee { public override void Making() { Console.WriteLine("原味咖啡"); } } } WhiteCoffee.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Practical { /// <summary> /// 牛奶咖啡 /// </summary> public class WhiteCoffee : MakeCoffee { public override void Making() { Console.WriteLine("牛奶咖啡"); } } } MediumCupCoffee.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Practical { /// <summary> /// 中杯 /// </summary> public class MediumCupCoffee : Coffee { public override void Make() { MakeCoffee makeCoffee = this.MakeCoffee(); Console.Write("中杯"); makeCoffee.Making(); } } } LargeCupCoffee.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Practical { /// <summary> /// 大杯 /// </summary> public class LargeCupCoffee : Coffee { public override void Make() { MakeCoffee makeCoffee = this.MakeCoffee(); Console.Write("大杯"); makeCoffee.Making(); } } } Client.cs: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DesignPatterns.BridgePattern.Practical { class Client { static void Main(string[] args) { MakeCoffeeSingleton whiteCoffeeSingleton = new MakeCoffeeSingleton(new WhiteCoffee()); // 中杯牛奶咖啡 MediumCupCoffee mediumWhiteCoffee = new MediumCupCoffee(); mediumWhiteCoffee.Make(); // 大杯牛奶咖啡 LargeCupCoffee largeCupWhiteCoffee = new LargeCupCoffee(); largeCupWhiteCoffee.Make(); MakeCoffeeSingleton blackCoffeeSingleton = new MakeCoffeeSingleton(new BlackCoffee()); // 中杯原味咖啡 MediumCupCoffee mediumBlackCoffee = new MediumCupCoffee(); mediumBlackCoffee.Make(); // 大杯牛奶咖啡 LargeCupCoffee largeCupBlackCoffee = new LargeCupCoffee(); largeCupBlackCoffee.Make(); } } } 運(yùn)行結(jié)果: 中杯牛奶咖啡 大杯牛奶咖啡 中杯原味咖啡 大杯原味咖啡 請按任意鍵繼續(xù). . . 5、橋接模式應(yīng)用分析 橋接模式可以適用于以下情形: 不希望在抽象與實(shí)現(xiàn)部分之間有固定的綁定關(guān)系; 類的抽象以及它的實(shí)現(xiàn)都應(yīng)該可以通過生成子類的方法加以擴(kuò)充。這時橋接模式可以對不同的抽象接口和實(shí)現(xiàn)部分進(jìn)行組合,并分別對它們進(jìn)行擴(kuò)充; 對抽象的實(shí)現(xiàn)部分進(jìn)行修改應(yīng)對客戶不產(chǎn)生影響,即客戶的代碼不必重新編譯; 想對客戶完全隱藏抽象的實(shí)現(xiàn)部分; 想在多個對象間共享實(shí)現(xiàn),但同時要求客戶并不知道這點(diǎn)。 橋接模式具有以下特點(diǎn): 分離接口及其實(shí)現(xiàn)部分,一個實(shí)現(xiàn)未必不變地綁定在一個接口上。抽象類的實(shí)現(xiàn)可以在運(yùn)行時刻進(jìn)行配置,一個對象甚至可以在運(yùn)行時刻改變它的實(shí)現(xiàn); 將Abstraction與Implementor分離有助于降低對實(shí)現(xiàn)部分編譯時刻的依賴性;當(dāng)改變一個實(shí)現(xiàn)類時,并不需要重新編譯Abstraction類和Client類。為了保證一個類庫的不同版本之間的兼容,需要有這個特性; 接口與實(shí)現(xiàn)分離有助于分層,從而產(chǎn)生更好的結(jié)構(gòu)化系統(tǒng)。系統(tǒng)的高層部分僅需要知道Abstraction和Implementor即可; 提高可擴(kuò)充性。可以獨(dú)立的對Abstraction和Implementor層次結(jié)構(gòu)進(jìn)行擴(kuò)充; 實(shí)現(xiàn)細(xì)節(jié)對Client透明??梢詫lient隱藏實(shí)現(xiàn)細(xì)節(jié),如共享Implementor對象以及相應(yīng)的引用計數(shù)機(jī)制。 |
|
|