簡體   English   中英

實施適配器模式時的困惑

[英]Confusion in implementing adapter pattern

我正在學習適配器模式,並使用以下鏈接查看代碼。 我的代碼和示例代碼的區別在於,我刪除了ITarget接口,並在Client中直接創建了對象。

我知道使用接口的重要性,但是確實需要使用接口,更具體地說,通過不創建接口來違反 接口模式規則嗎?

適配器模式示例

我的代碼(無界面)

class Program
    {
        static void Main(string[] args)
        {
            Adapter obj = new Adapter();
            Client client = new Client(obj);

            client.MakeRequest();
        }
    }

    public class Client
    {
        private Adapter _target;

        public Client(Adapter target)
        {
            _target = target;
        }

        public void MakeRequest()
        {
            _target.MethodA();
        }
    }


    public class Adaptee
    {
        public void MethodB()
        {
            Console.WriteLine("MethodB called");
        }
    }


    public class Adapter 
    {
        Adaptee _adaptee = new Adaptee();

        public void MethodA()
        {
            _adaptee.MethodB();
        }
    }

謝謝。

適配器的全部目的是,可以在需要某種特定類型(而不是適配器類型)的地方使用適配器。

假設您有一個方法MyMethod(MyParameterType m) 該方法需要一個類型為MyParameterType的參數。 但是您沒有這種類型的對象。 相反,您有一個具有類似功能的對象(可能來自第三方庫)。 但是,此對象不是MyParameterType類型,而是MyOtherType類型。 當然,您不能直接將對象傳遞給方法。 這就是適配器起作用的地方。

您需要一個對象來傳遞給方法。 因此,此對象的類型MyParameterTypeMyParameterType 可能是接口或類。 因此, Adapter必須實現或繼承此類型。 否則,這是沒有意義的。 您將擁有另一個具有與MyOtherType類型的對象相同功能的類,但是您無法在任何地方使用它。

總而言之,適配器用於彌合體系結構不匹配。 當您有多個需要一起播放但不應該一起播放的庫時,通常會發生這種情況。 如果只有您自己開發的代碼,則幾乎不需要適配器,因為可以讓對象僅實現所需的接口。 這在第三方代碼中是不可能的。 因此,您為此引入了適配器。 因此,最后,適配器偽裝了一個對象,使客戶端看起來很熟悉,即使它不是。 該界面對於使其熟悉是必不可少的。 是的,您的代碼不是適配器。

這里的問題是您已將Client顯式地耦合到適配器,並且隱式地耦合到該適配器如何工作的行為。

當您開始使用依賴項注入時,接口和此模式將奏效。

假設我有:

public Client(IAdapter target) ...

現在, 我可以更改適配器實現的行為,而無需完全更改 Client類:

interface IAdapter
{
    void MethodA();
}

interface IAdaptee
{
    void MethodB();
}

class Adapter<TAdaptee> : IAdapter where TAdaptee : IAdaptee, new()
{
    private TAdaptee _adaptee;

    public Adapter()
    {
        _adaptee = new TAdaptee();
    }

    public void MethodA()
    {
        _adaptee.MethodB();
    }
}

class AdapteeA : IAdaptee
{
    public void MethodB()
    {
        Console.WriteLine("AdapteeA");
    }
}

class AdapteeB : IAdaptee
{
    public void MethodB()
    {
        Console.WriteLine("AdapteeB");
    }
}

然后使用NInject之類的東西綁定您的系統:

class Program
{
    private static StandardKernel _kernel;

    static void Main(string[] args)
    {
        _kernel = new StandardKernel();

        _kernel.Bind<IAdapter>().To<Adapter<AdapteeA>>();

        var adapter = _kernel.Get<IAdapter>();

        adapter.MethodA();
    }
}

您可以更改適配器和適配器,而無需客戶知道其區別。 即客戶端從兩者分離

再次說明這一點,我可以更改為AdapteeB

_kernel.Bind<IAdapter>().To<Adapter<AdapteeB>>();

它確實在進一步發展,例如逆方差,但這超出了范圍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM