2017-04-20 25 views
0

我想知道我是否正確理解這種模式。假設我們有接口不兼容。 函數來自第三方dll的Printer()需要IHPPrinter,但我們的對象沒有實現這種干涉...所以最後我們必須實現這個接口並返回我們的方法的實現,就像在下面的代碼中一樣? :) 第二個問題是,如果我們不爲方法DocumentsInQueue提供實現,將會拋出異常。是否有可能阻止調用這種方法?C中的適配器模式#

class Program 
{ 
    static void Main(string[] args) 
    { 
     EpsonPrinter _epsonPrinter = new EpsonPrinter(); 
     Printer(_epsonPrinter); 
     Console.ReadKey(); 
    } 


    public static void Printer(IHPPrinter hpPrinter) 
    { 
     hpPrinter.PrintDocument(); 
    } 

    public interface IHPPrinter 
    { 
     void PrintDocument(); 
     int DocumentsInQueue(); 
    } 
    public interface IEpsonPrinter 
    { 
     void Print(); 
    } 

    public class EpsonPrinter : IEpsonPrinter, IHPPrinter 
    { 
     public int DocumentsInQueue() 
     { 
      throw new NotImplementedException(); 
     } 

     public void Print() 
     { 
      this.PrintDocument(); 
     } 

     public void PrintDocument() 
     { 
      Console.WriteLine("Printing from Epson printer..."); 
     } 


    } 
} 
+2

您還沒有實現適配器模式,基本上是要實現在同一類兩個接口。 –

回答

1

Interfaces (C# Programming Guide)

當一個類或結構實現的接口,所述類或結構必須提供所有的接口定義成員的實現。

您無法阻止撥打DocumentsInQueue()。如果你沒有實現它,你應該拋出一個NotSupportedException

投擲NotSupportedException異常

你已經從需要你重寫了一些方法的抽象類繼承。但是,您只准備爲這些子集提供實現。對於您決定不實現的方法,可以選擇拋出NotSupportedException。

例如:

public int DocumentsInQueue() 
{ 
    throw new NotSupportedException("DocumentsInQueue is not supported in EpsonPrinter."); 
} 
2

你提供的代碼不是適配器模式的一個例子。

適合您例子的適配器應該是它自己的類,可能類似於EpsonPrinterToHpPrinterAdapter。它將執行IHPPrinter並將IEpsonPrinter實現的實例作爲其構造函數的參數。

然後,您會將EpsonPrinterToHpPrinterAdapter的實例傳遞給期望IHPPrinter的方法。該適配器類然後將所有調用從IHPPrinter方法轉換爲從構造函數調用IEpsonPrinter的引用。

適配器模式的主要目標是讓類B的行爲像類A一樣儘可能地將行爲從一個轉換到另一個。你不能阻止一個成員被調用,你必須提供某種特殊的實現來適應你正在調整的類。

在你的具體的例子,這將是相當瑣碎的PrintDocument將呼叫直接傳遞給Print,但調用DocumentsInQueue是比較困難的,因爲沒有對IEpsonPrinter不匹配的成員。您可能需要分別跟蹤並返回計數,每調用一次PrintDocument就遞增一個內部計數器,並在完成時遞減計數。

當您不控制這些代碼的所有部分時,這種類型的模式變得非常重要。如果EpsonPrinterPrinter類都在不能修改的第三方庫中定義,則可以使用此模式將它們連接在一起。

我已經採取了你的榜樣,並提出使用適配器模式需要作出的改變:

class Program 
    { 
     static void Main(string[] args) 
     { 
      EpsonPrinter epsonPrinter = new EpsonPrinter(); 
      EpsonPrinterToHPPrinterAdapter adapter = new EpsonPrinterToHPPrinterAdapter(epsonPrinter); 
      Printer(adapter); 
      Console.ReadKey(); 
     } 


     public static void Printer(IHPPrinter hpPrinter) 
     { 
      hpPrinter.PrintDocument(); 
     } 

     public interface IHPPrinter 
     { 
      void PrintDocument(); 
      int DocumentsInQueue(); 
     } 
     public interface IEpsonPrinter 
     { 
      void Print(); 
     } 

     public class EpsonPrinterToHPPrinterAdapter : IHPPrinter 
     { 

      public EpsonPrinterToHPPrinterAdapter(IEpsonPrinter epsonPrinter) 
      { 
       EpsonPrinter = epsonPrinter; 
       _queueCount = 0; 
      } 

      private int _queueCount; 

      public IEpsonPrinter EpsonPrinter { get; } 

      public void PrintDocument() 
      { 
       _queueCount++; 
       EpsonPrinter.Print(); 
       _queueCount--; 
      } 

      public int DocumentsInQueue() 
      { 
       return _queueCount; 
      } 
     } 

     public class EpsonPrinter : IEpsonPrinter 
     { 
      public void Print() 
      { 
       Console.WriteLine("Printing from Epson printer..."); 
      } 
     } 
    } 
+0

太棒了,我明白你的方法,比我的代碼好多了。 – tylkonachwile

+0

但我認爲我的意思是,我的代碼不正確執行這種模式。你怎麼看? – tylkonachwile

+0

正確,您的代碼沒有使用適配器模式。我不認爲你所做的是一個特定的名字。 –