2017-04-20 62 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

正确,您的代码没有使用适配器模式。我不认为你所做的是一个特定的名字。 –