繁体   English   中英

适配器设计模式的需求是什么?

[英]what is the need of Adapter Design pattern?

在下面的适配器设计模式示例代码中,为什么要引入新类而不是在客户端中使用多个接口?

interface ITarget
{
  List<string> GetProducts();
}


public class VendorAdaptee
{
   public List<string> GetListOfProducts()
   {
      List<string> products = new List<string>();
      products.Add("Gaming Consoles");
      products.Add("Television");
      products.Add("Books");
      products.Add("Musical Instruments");
      return products;
   }
}


class VendorAdapter:ITarget
{
   public List<string> GetProducts()
   {
      VendorAdaptee adaptee = new VendorAdaptee();
      return adaptee.GetListOfProducts();
   }
}


class ShoppingPortalClient
{
   static void Main(string[] args)
   {
      ITarget adapter = new  VendorAdapter();
      foreach (string product in adapter.GetProducts())
      {
        Console.WriteLine(product);
      }
      Console.ReadLine();
   }
}

我有以下与上述代码相关的查询。

  • 如果ShoppingPortalClient直接继承VendorAdaptee,该怎么办?
  • 在哪种情况下我们需要适配器类?
  • 为什么不是简单的继承需要的类,创建这个模式来访问另一个类方法?

有时您有一个无法更改的给定API(遗留/外部库/等等),并且您希望使您的classes能够使用该API而无需更改其代码。

假设您使用的是具有ISomethingToSerialize的API

public interface ISomethingToSerialize
{
    object[] GetItemsToSerialize();
}

该API还具有Serialize功能:

public class SerializationServices
{
    byte[] Serialize(ISomethingToSerialize objectToSerialize);
}

现在你的代码中有一个class ,你不想或不能改变它,我们称之为MyUnchangeableClass

这个class没有实现ISomethingToSerialize但你要使用序列化它API ,所以你创建AdapterClass它们实现ISomethingToSerialize允许MyUnchangeableClass使用它本身不执行它:

public class AdapterClass : ISomethingToSerialize
{
    public AdapterClass(MyUnchangeableClass instance)
    {
        mInstance = instance;
    }

    MyUnchangeableClass mInstance;

    public object[] GetItemsToSerialize()
    {
        return mInstance.SomeSpecificGetter();
    }
}

现在你可以使用了

MyUnchangeableClass instance = ... //Constructor or factory or something...
AdapterClass adapter = new AdapterClass(instance)
SerializationServices.Serialize(adapter);

序列化MyUnchangeableClass一个实例,即使它本身不符合API的要求。

你的想法完全错了。 VendorAdaptee是生成数据的代码实例,其中ShoppingPortalClient是想要使用它的人。

让我解释一下现实世界的情况。 您正在实施该商店,并且其他人已实施服务以向您提供有关其产品的数据(VendorAdaptee)。 这样做的简单方法是简单地调用他们的方法并使用数据,对吧? 但这是他们的服务,他们可能希望稍后更改它,而您不想上传整个解决方案并发布新版本。 因此,您需要一个适配器,以确保数据将以您需要的格式发送到您的实际代码,而您根本不关心您支持的地址,方法名称或数据格式供应商。


关于你的问题:

遗传绝不是这种情况。 从概念上讲,商店不是任何供应商。 考虑到代码,你在这两个代码中没有任何相似之处,并且行为完全不同。 一个是提供数据而另一个是使用它。

您使用适配器的主要原因是您不想搞砸的遗留代码 - 或者您不适合某个界面的第三方。

还有其他原因,通常取决于您如何发现更容易开发以及使用适配器设计模式对您有意义。 但我认为它在其他情况下并不十分有用。

首先,我也不认为这是适配器模式的一个很好的例子。 当你不能在你的类中直接使用一种特定类(比如说A)时,适配器模式是很有意义的(比如说B),而是你实现了另一个类(比如说C),它可以在你的类中直接使用(B)和它(C)可以直接使用第一个(A)。

你可能会问B不能直接使用A的例子。很少。

  • A的方法不返回B理想需要的类型。
  • 因此,我们不要在B内部添加B的转换需求。相反,我们负责C为B执行此操作。
  • B含有A等可能看起来不自然。

回到你的问题

(1)如果你问,这是有意义的,

什么,如果ShoppingPortalClient直接'使用' VendorAdaptee?

仅仅因为它是主类,它已被用作演示,而不是显示结构。 还有一件事要补充,只是因为你想要调用另一个类的方法,除非它有意义,否则不要继承它。 在这种情况下,优选组合物。 对于为什么不“使用”的问题,假设它不能。 但你宁愿问为什么不能。 我在这个例子中给出的答案就是假设调用Adaptee是不自然的。 这就是为什么我说这不是一个好例子。 :)

(2),(3)我认为你可以从我迄今提供的描述中得到答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM