2014-04-02 75 views
0

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

我知道使用接口的重要性,但是否真的有必要使用的界面,更具體地說,是沒有創建界面,我是違反適配器模式規則

Adapter Pattern Example

我的代碼(不包括接口)

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

感謝。

回答

2

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

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

總結,適配器用於彌補架構不匹配。當你有幾個需要一起玩但不應該這樣做的庫時,通常會發生這種情況。如果您只有自己開發的代碼,那麼適配器很少是必需的,因爲您可以讓對象實現您所需的接口。這在第三方代碼中是不可能的。所以你介紹適配器。所以最終,適配器會掩蓋一個對象,讓客戶看起來很熟悉,即使它不是。界面是必要的,以使其熟悉。所以是的,你的代碼不是一個適配器。

+0

+1。很好的解釋。謝謝。 –

1

這裏的問題是您已經明確地將客戶端耦合到適配器,並隱含地表示該適配器的工作方式。

當你開始使用依賴注入時,接口和這個模式會得到回報。

假設我有:

public Client(IAdapter target) ... 

現在我可以改變適配器實現的行爲,而客戶端類正在發生任何變化:

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綁定up your system:

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>>(); 

它走的更遠也有類似的事情禁忌變化,但這超出了範圍。

+0

+1。很好的解釋。 –