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

时间:2016-08-28 07:06:25

标签: c# asp.net .net design-patterns adapter

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

123123,ABC,2016-08-18,18:53:53,123123_TTT,121212,343434
456456,ABC,2016-08-18,18:53:53,456456_TTT,323232,223344
789789,ABC,2016-08-18,18:53:53,789789_TTT,567774,223452
123123,ABC,2016-02-15,18:53:53,123123_TTT,121212,343434

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

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

4 个答案:

答案 0 :(得分:7)

有时您拥有一个无法更改的给定API(旧版/外部库等等),并且您希望让classes能够使用该API而无需更改其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

序列化Guid的实例,即使它本身并不符合API的要求。

答案 1 :(得分:4)

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

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

关于您的问题:

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

答案 2 :(得分:2)

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

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

答案 3 :(得分:2)

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

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

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

回到你的问题

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

  

如果ShoppingPortalClient直接'使用' VendorAdaptee,该怎么办?

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

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