引言
例如我有好幾個專案,需要外包出去做各種型別的測驗,不同的公司基礎費用不同,不同的測驗型別價格也是不同的,此時不同的專案選擇不同的公司和不同型別的測驗進行測驗價格都是不同的,于是我們可以創建一個專案抽象類,一個公司抽象類,一個測驗型別抽象類,然后實作各自的具體類,不同的專案使用不同的公司和測驗型別,進行測驗,抽象化與實作化解耦,二者可以獨立變化,我們將這種通過提供抽象化和實作化之間的橋接結構,來實作二者的解耦的型別稱為橋接模式,
概念
橋接(Bridge)是用于把抽象化與實作化解耦,使得二者可以獨立變化,這種型別的設計模式屬于結構型模式,它通過提供抽象化和實作化之間的橋接結構,來實作二者的解耦,
這種模式涉及到一個作為橋接的介面,使得物體類的功能獨立于介面實作類,這兩種型別的類可被結構化改變而互不影響,
結構圖

橋接(Bridge)模式中的主要角色:
- 抽象化(Abstraction)角色:定義抽象類,并包含一個對實作化物件的參考,
- 擴展抽象化(Refined Abstraction)角色:是抽象化角色的子類,實作父類中的業務方法,并通過組合關系呼叫實作化角色中的業務方法,
- 實作化(Implementor)角色:定義實作化角色的介面,供擴展抽象化角色呼叫,
- 具體實作化(Concrete Implementor)角色:給出實作化角色介面的具體實作,
具體實作
以引言中的示例進行實作,一個產品需要外包出去進行測驗,
涉及三個角色:產品、外包公司、測驗型別
using System; namespace Bridge { class Program { static void Main(string[] args) { Company beijingCompany = new BeijingCompany(); TestType manualTest = new ManualTest(); Prodeuct managementProdeuct = new ManagementProdeuct(beijingCompany, manualTest); managementProdeuct.Run(); Company shanghaiCompany = new ShanghaiCompany(); TestType autoTest = new AutoTest(); Prodeuct operationProdeuct = new ManagementProdeuct(shanghaiCompany, autoTest); operationProdeuct.Run(); Console.Read(); } } /// <summary> /// 軟體產品,抽象類 /// 充當抽象化角色 /// 將抽象部分與實作部分分離,使他們都可以獨立的變化 /// </summary> public abstract class Prodeuct { private readonly Company _company; private readonly TestType _testType; // 使用組合,一個產品外包出去,需要一個公司進行不同測驗型別的測驗 public Prodeuct(Company company, TestType testType) { this._company = company; this._testType = testType; } public string Name { get; set; } // 執行實作部分 public void Run() { Console.WriteLine($"{this._company.Name}對產品{Name}進行{this._testType.Name},總共花費時間{this._company.BaseTime + this._testType.RunTime},"); Console.WriteLine("======================================================"); } } /// <summary> /// 公司,對實作部分進行抽象 /// </summary> public abstract class Company { public string Name { get; set; } public Double BaseTime { get; set; } } /// <summary> /// 測驗型別,對實作部分進行抽象 /// </summary> public abstract class TestType { public string Name { get; set; } public Double RunTime { get; set; } } /// <summary> /// 管理系統,擴展抽象化角色 /// </summary> public class ManagementProdeuct : Prodeuct { public ManagementProdeuct(Company company, TestType testType) : base(company, testType) { Name = "管理系統"; } } /// <summary> /// 運營系統,擴展抽象化角色 /// </summary> public class OperationProdeuct : Prodeuct { public OperationProdeuct(Company company, TestType testType) : base(company, testType) { Name = "運營系統"; } } /// <summary> /// 公司抽象類具體實作,具體實作化角色 /// </summary> public class BeijingCompany : Company { public BeijingCompany() { Name = "北京公司"; BaseTime = 200; } } /// <summary> /// 公司抽象類具體實作,具體實作化角色 /// </summary> public class ShanghaiCompany : Company { public ShanghaiCompany() { Name = "上海公司"; BaseTime = 100; } } /// <summary> ///測驗型別抽象類具體實作,具體實作化角色 /// </summary> public class ManualTest : TestType { public ManualTest() { Name = "手工測驗"; RunTime = 30; } } /// <summary> ///測驗型別抽象類具體實作,具體實作化角色 /// </summary> public class AutoTest : TestType { public AutoTest() { Name = "自動測驗"; RunTime = 10; } } }
運行后結果:
北京公司對產品管理系統進行手工測驗,總共花費時間230, ====================================================== 上海公司對產品管理系統進行自動測驗,總共花費時間110, ======================================================
適用場景
- “抽象部分”和“實作部分”可以以繼承的方式獨立擴展而互不影響,在程式運行時可以動態將一個抽象化子類的物件和一個實作化子類的物件進行組合,即系統需要對抽象化角色和實作化角色進行動態耦合,
- 一個類存在兩個(或多個)獨立變化的維度,且這兩個(或多個)維度都需要獨立進行擴展,
- 對于那些不希望使用繼承或因為多層繼承導致系統類的個數急劇增加的系統,橋接模式尤為適用,
優缺點
優點
- 抽象與實作分離,擴展能力強,
- 符合開閉原則,
- 符合合成復用原則,
- 單一職責原則, 抽象部分專注于處理高層邏輯, 實作部分處理平臺細節,
缺點
- 由于聚合關系建立在抽象層,要求開發者針對抽象化進行設計與編程,能正確地識別出系統中兩個獨立變化的維度,這增加了系統的理解與設計難度,
與裝飾器模式區別
- 裝飾器模式是為了動態地給一個物件增加功能,而橋接模式時為了讓類在多個維度上自由擴展,
- 裝飾器模式的裝飾者和被裝飾者需要繼承自同一父類,而橋接模式通常不需要;
- 裝飾器模式通常可以嵌套使用,而橋接模式不能,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/228924.html
標籤:設計模式
上一篇:C#設計模式-裝飾器模式(Decorator Pattern)
下一篇:Java中的單例模式最全決議
