C#設計模式-橋接模式(Bridge Pattern)

引言

例如我有好幾個項目,須要外包出去作各類類型的測試,不一樣的公司基礎費用不一樣,不一樣的測試類型價格也是不一樣的。此時不一樣的項目選擇不一樣的公司和不一樣類型的測試進行測試價格都是不一樣的。因而咱們能夠建立一個項目抽象類,一個公司抽象類,一個測試類型抽象類,而後實現各自的具體類,不一樣的項目使用不一樣的公司和測試類型,進行測試。抽象化與實現化解耦,兩者能夠獨立變化。咱們將這種經過提供抽象化和實現化之間的橋接結構,來實現兩者的解耦的類型稱爲橋接模式。編程

概念

橋接(Bridge)是用於把抽象化與實現化解耦,使得兩者能夠獨立變化。這種類型的設計模式屬於結構型模式,它經過提供抽象化和實現化之間的橋接結構,來實現兩者的解耦。
這種模式涉及到一個做爲橋接的接口,使得實體類的功能獨立於接口實現類。這兩種類型的類可被結構化改變而互不影響。設計模式

結構圖

橋接(Bridge)模式中的主要角色:

  • 抽象化(Abstraction)角色:定義抽象類,幷包含一個對實現化對象的引用。
  • 擴展抽象化(Refined Abstraction)角色:是抽象化角色的子類,實現父類中的業務方法,並經過組合關係調用實現化角色中的業務方法。
  • 實現化(Implementor)角色:定義實現化角色的接口,供擴展抽象化角色調用。
  • 具體實現化(Concrete Implementor)角色:給出實現化角色接口的具體實現。

具體實現

以引言中的示例進行實現。一個產品須要外包出去進行測試。測試

涉及三個角色:產品、外包公司、測試類型this

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;
        }
    }
}

運行後結果:spa

北京公司對產品管理系統進行手工測試,總共花費時間230。
======================================================
上海公司對產品管理系統進行自動測試,總共花費時間110。
======================================================

適用場景

  • 「抽象部分」和「實現部分」能夠以繼承的方式獨立擴展而互不影響,在程序運行時能夠動態將一個抽象化子類的對象和一個實現化子類的對象進行組合,即系統須要對抽象化角色和實現化角色進行動態耦合。
  • 一個類存在兩個(或多個)獨立變化的維度,且這兩個(或多個)維度都須要獨立進行擴展。
  • 對於那些不但願使用繼承或由於多層繼承致使系統類的個數急劇增長的系統,橋接模式尤其適用。

優缺點

優勢

  • 抽象與實現分離,擴展能力強。
  • 符合開閉原則。
  • 符合合成複用原則。
  • 單一職責原則。 抽象部分專一於處理高層邏輯, 實現部分處理平臺細節。

缺點

  • 因爲聚合關係創建在抽象層,要求開發者針對抽象化進行設計與編程,能正確地識別出系統中兩個獨立變化的維度,這增長了系統的理解與設計難度。

與裝飾器模式區別

  • 裝飾器模式是爲了動態地給一個對象增長功能,而橋接模式時爲了讓類在多個維度上自由擴展。
  • 裝飾器模式的裝飾者和被裝飾者須要繼承自同一父類,而橋接模式一般不須要;
  • 裝飾器模式一般能夠嵌套使用,而橋接模式不能。
相關文章
相關標籤/搜索