設計模式之-適配器模式

定義:

適配器模式(Adapter Pattern) :將一個接口轉換成客戶但願的另外一個接口,適配器模式使接口不兼容的那些類能夠一塊兒工做,其別名爲包裝器(Wrapper)。適配器模式既能夠做爲類結構型模式,也能夠做爲對象結構型模式。git

適配器模式參與者

  • Target:客戶(Client)所期待的接口。目標能夠是具體的或抽象的類,也能夠是接口。
  • Adapter:經過在內部包裝一個Adaptee對象,把源接口轉換成目標接口。
  • Adaptee:須要適配的類

適配器模式基本代碼

1.類適配器結構實現

Target類:github

namespace AdapterPattern.BasicStructure.ClassAdapter
{
    /// <summary>
    /// 接口
    /// </summary>
    interface ITarget
    {
        void Request();
    }
}

Adapter類:編程

namespace AdapterPattern.BasicStructure.ClassAdapter
{
    class Adapter : Adaptee, ITarget
    {
        public void Request()
        {
            this.SpecificRequest();
        }
    }
}

Adaptee類:app

namespace AdapterPattern.BasicStructure.ClassAdapter
{
    /// <summary>
    /// 須要要適配的類
    /// </summary>
    class Adaptee
    {
        /// <summary>
        /// 特殊的請求
        /// </summary>
        public void SpecificRequest()
        {
            Console.WriteLine("特殊請求!");
        }
    }
}

客戶端調用代碼:編程語言

    static void Main(string[] args)
    {
        try
        {
            {//BasicStructure-ClassAdapter
                BasicStructure.ClassAdapter.ITarget target = new BasicStructure.ClassAdapter.Adapter();
                //表面看像是調用了Request()方法,但實際是調用了SpecificRequest()方法
                target.Request();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadKey();
    }

結果以下:this

2.對象適配器結構實現

 Target類;spa

namespace AdapterPattern.BasicStructure.ObjectAdapter
{
    /// <summary>
    /// 接口
    /// </summary>
    interface ITarget
    {
        void Request();
    }
}

Adapter類:code

namespace AdapterPattern.BasicStructure.ObjectAdapter
{
    class Adapter : ITarget
    {
        private Adaptee _adaptee = new Adaptee();

        public void Request()
        {
            _adaptee.SpecificRequest();
        }
    }
}

Adaptee類:orm

namespace AdapterPattern.BasicStructure.ObjectAdapter
{
    /// <summary>
    /// 須要要適配的類
    /// </summary>
    class Adaptee
    {
        /// <summary>
        /// 特殊的請求
        /// </summary>
        public void SpecificRequest()
        {
            Console.WriteLine("特殊請求!");
        }
    }
}

客戶端調用代碼:對象

    static void Main(string[] args)
    {
        try
        {
            {//BasicStructure-ObjectAdapter
                BasicStructure.ObjectAdapter.ITarget target = new BasicStructure.ObjectAdapter.Adapter();
                target.Request();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadKey();
    }

結果以下:

用適配器模式實現筆記本電腦獲取電壓

場景模擬:以筆記本電腦要用220V的電壓爲例

1.類適配器結構實現

Computer(電腦)類——Target類

namespace AdapterPattern.SituationSimulation.ClassAdapter
{
    /// <summary>
    /// 接口
    /// </summary>
    interface IComputer
    {
        void GetVoltage();
    }
}

Transformer(變壓器)類——Adapter類

namespace AdapterPattern.SituationSimulation.ClassAdapter
{
    /// <summary>
    /// 變壓器
    /// </summary>
    class Transformer : NoteBook, IComputer
    {
        public void GetVoltage()
        {
            this.Get220Voltage();
        }
    }
}

NoteBook(筆記本)類——Adaptee類

namespace AdapterPattern.SituationSimulation.ClassAdapter
{
    /// <summary>
    /// 筆記本電腦類
    /// </summary>
    class NoteBook
    {
        /// <summary>
        /// 獲取220V 電壓
        /// 系統中已經存在的類,與ITarget接口不兼容,又很差修改這個類
        /// </summary>
        public void Get220Voltage()
        {
            Console.WriteLine("我要使用220V 電壓才能正常工做!");
        }
    }
}

客戶端調用代碼:

    static void Main(string[] args)
    {
        try
        {
            {//SituationSimulation-ClassAdapter
                SituationSimulation.ClassAdapter.IComputer target = new SituationSimulation.ClassAdapter.Transformer();
                target.GetVoltage();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadKey();
    }

結果以下:

2.對象適配器結構實現

Computer(電腦)類——Target類

namespace AdapterPattern.SituationSimulation.ObjectAdapter
{
    /// <summary>
    /// 接口
    /// </summary>
    interface IComputer
    {
        void GetVoltage();
    }
}

Transformer(變壓器)類——Adapter類

namespace AdapterPattern.SituationSimulation.ObjectAdapter
{
    /// <summary>
    /// 變壓器
    /// </summary>
    class Transformer :  IComputer
    {
        private NoteBook _noteBook = new NoteBook();
        public void GetVoltage()
        {
            _noteBook.Get220Voltage();
        }
    }
}

NoteBook(筆記本)類——Adaptee類

namespace AdapterPattern.SituationSimulation.ObjectAdapter
{
    /// <summary>
    /// 筆記本電腦類
    /// </summary>
    class NoteBook
    {
        /// <summary>
        /// 獲取220V 電壓
        /// 系統中已經存在的類,與ITarget接口不兼容,又很差修改這個類
        /// </summary>
        public void Get220Voltage()
        {
            Console.WriteLine("我要使用220V 電壓才能正常工做!");
        }
    }
}

客戶端調用代碼:

    static void Main(string[] args)
    {
        try
        {
            {//SituationSimulation-ObjectAdapter
                SituationSimulation.ObjectAdapter.IComputer target = new SituationSimulation.ObjectAdapter.Transformer();
                target.GetVoltage();
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Console.ReadKey();
    }

結果以下:

優勢:

  • 將目標類和適配者類解耦,經過引入一個適配器類來重用現有的適配者類,而無須修改原有代碼。
  • 增長了類的透明性和複用性,將具體的實現封裝在適配者類中,對於客戶端類來講是透明的,並且提升了適配者的複用性。
  • 靈活性和擴展性都很是好,經過使用配置文件,能夠很方便地更換適配器,也能夠在不修改原有代碼的基礎上增長新的適配器類,徹底符合「開閉原則」。

類適配器模式還具備以下優勢:

  因爲適配器類是適配者類的子類,所以能夠在適配器類中置換一些適配者的方法,使得適配器的靈活性更強。

對象適配器模式還具備以下優勢:

  一個對象適配器能夠把多個不一樣的適配者適配到同一個目標,也就是說,同一個適配器能夠把適配者類和它的子類都適配到目標接口。

缺點:

類適配器模式的缺點以下:

對於Java、C#等不支持多重繼承的語言,一次最多隻能適配一個適配者類,並且目標抽象類只能爲抽象類,不能爲具體類,其使用有必定的侷限性,不能將一個適配者類和它的子類都適配到目標接口。

對象適配器模式的缺點以下:

與類適配器模式相比,要想置換適配者類的方法就不容易。若是必定要置換掉適配者類的一個或多個方法,就只好先作一個適配者類的子類,將適配者類的方法置換掉,而後再把適配者類的子類當作真正的適配者進行適配,實現過程較爲複雜。

適用環境:

在如下狀況下可使用適配器模式:

  • 系統須要使用現有的類,而這些類的接口不符合系統的須要。
  • 想要創建一個能夠重複使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在未來引進的類一塊兒工做。

總結:

  • 結構型模式描述如何將類或者對象結合在一塊兒造成更大的結構。
  • 適配器模式用於將一個接口轉換成客戶但願的另外一個接口,適配器模式使接口不兼容的那些類能夠一塊兒工做,其別名爲包裝器。適配器模式既能夠做爲類結構型模式,也能夠做爲對象結構型模式。
  • 適配器模式包含四個角色:目標抽象類定義客戶要用的特定領域的接口;適配器類能夠調用另外一個接口,做爲一個轉換器,對適配者和抽象目標類進行適配,它是適配器模式的核心;適配者類是被適配的角色,它定義了一個已經存在的接口,這個接口須要適配;在客戶類中針對目標抽象類進行編程,調用在目標抽象類中定義的業務方法。
  • 在類適配器模式中,適配器類實現了目標抽象類接口並繼承了適配者類,並在目標抽象類的實現方法中調用所繼承的適配者類的方法;在對象適配器模式中,適配器類繼承了目標抽象類並定義了一個適配者類的對象實例,在所繼承的目標抽象類方法中調用適配者類的相應業務方法。
  • 適配器模式的主要優勢是將目標類和適配者類解耦,增長了類的透明性和複用性,同時系統的靈活性和擴展性都很是好,更換適配器或者增長新的適配器都很是方便,符合「開閉原則」;類適配器模式的缺點是適配器類在不少編程語言中不能同時適配多個適配者類,對象適配器模式的缺點是很難置換適配者類的方法。
  • 適配器模式適用狀況包括:系統須要使用現有的類,而這些類的接口不符合系統的須要;想要創建一個能夠重複使用的類,用於與一些彼此之間沒有太大關聯的一些類一塊兒工做。

 

源代碼地址:https://github.com/houzhenhuang/DesignPattern

相關文章
相關標籤/搜索