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

use*_*872 4 .net c# asp.net design-patterns adapter

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

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();
   }
}
Run Code Online (Sandbox Code Playgroud)

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

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

Tam*_*red 7

有时您有一个无法更改的给定API(旧版/外部库/等等),并且您希望classes能够在不更改其代码的情况下使用该API.

假设你使用的API有一个 ISomethingToSerialize

public interface ISomethingToSerialize
{
    object[] GetItemsToSerialize();
}
Run Code Online (Sandbox Code Playgroud)

该API还具有以下Serialize功能:

public class SerializationServices
{
    byte[] Serialize(ISomethingToSerialize objectToSerialize);
}
Run Code Online (Sandbox Code Playgroud)

现在你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();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你可以使用了

MyUnchangeableClass instance = ... //Constructor or factory or something...
AdapterClass adapter = new AdapterClass(instance)
SerializationServices.Serialize(adapter);
Run Code Online (Sandbox Code Playgroud)

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


Ash*_*ous 5

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

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


关于你的问题:

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