适配器设计模式的需求是什么?
本文关键字:是什么 需求 设计模式 适配器 | 更新日期: 2023-09-27 18:04:16
在下面的适配器设计模式示例代码中,为什么要引入一个新类而不是在客户机中使用多个接口?
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而不改变他们的代码。
假设你使用的API有一个ISomethingToSerialize
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)。最简单的方法就是调用它们的方法并使用数据,对吗?但这是他们的服务,当你不想上传整个解决方案并发布新版本时,他们可能会想稍后更改它。因此,您需要一个适配器,以确保数据将以您需要的格式发送到您的实际代码,并且您根本不关心您的供应商支持的地址,方法名称或数据格式。
关于你的问题:
继承在任何方面都不是这种情况。从概念上讲,商店在任何方面都不是供应商。考虑到代码,这两者中没有任何相似之处,而且行为完全不同。一个是提供数据,另一个是使用数据。
您使用适配器的主要原因是您不想弄乱遗留代码-或者您不适合某个接口的第三方。
还有其他原因,通常取决于您如何发现更容易开发,以及使用适配器设计模式对您是否有意义。但我不认为它在其他情况下很有用。
首先我也不认为这是一个适配器模式的好例子。当你不能在你的类(比如B)中直接使用一种特定的类(比如A),而你实现另一个类(比如C),它可以直接在你的类(B)中使用,而它(C)可以直接使用第一个类(A)时,适配器模式就很有意义了。
你可能会问,B不能直接使用a的例子有哪些?
- A的方法没有返回b理想需要的类型。
- 所以我们不要把B的转换需求添加到B中,而是把责任交给C来为B做。
- B中含有a等可能看起来不自然
回到你的问题
如果你问,这是有意义的,如果ShoppingPortalClient直接'使用' VendorAdaptee怎么办?
只是因为它是主类,所以它被用作演示,而不是显示结构。还有一点需要补充,仅仅因为你想调用另一个类的方法,不要继承它,除非它是有意义的。在这种情况下,组合是首选。对于为什么不"使用"这个问题,只要假设它不能。但你宁愿问为什么不能。在这个例子中,我可以给出的答案是假设调用Adaptee是不自然的。这就是为什么我说这不是一个好的例子。:)
(2),(3)我想你可以从我目前提供的描述中得到答案。