适配器模式是一种结构型设计模式,它允许两个不兼容的接口之间能够相互通信。这种模式的名称来源于生活中的一个常见例子:电源适配器。当从美国购买的笔记本电脑充电器,其插头可能与欧洲国家的电源插座不匹配,这时就需要一个电源适配器来使两者能够连接。在软件设计中,也会遇到类似的情况,即客户端对象想要调用某个方法,但该方法的接口与客户端对象不兼容。这时,适配器模式就派上了用场。
在适配器模式中,有几个关键的参与者:
假设有一个在线购物门户网站,它在其首页上展示销售的产品。这些产品来自一个第三方供应商,该门户网站与该供应商合作销售产品。第三方供应商已经有一个库存系统,可以提供其正在销售的产品列表。但是,对于在线购物门户网站来说,没有可用的接口来调用第三方供应商的库存代码。
在这种情况下,想要调用与客户端(在线购物门户网站)代码不兼容的第三方供应商代码,因此可以应用“适配器设计模式”。首先,来看一下适配器模式在场景中的各个参与者:
下面是一个展示适配器模式的示例代码,将重新审视各种类,并将它们映射到适配器模式的参与者。
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();
}
}
在上面的代码中,参与者被映射为:
上述代码是自解释的,客户端有访问ITarget接口的权限,想要调用方法VendorAdaptee.GetListOfProduct(),但由于VendorAdaptee没有ITarget接口,因此需要创建一个适配器VendorAdapter。VendorAdapter实现了ITarget接口,并调用了被适配者的方法。
根据适配器如何调用被适配者,它可以被称为类适配器,即当适配器使用类继承来调用被适配者代码时。当它使用对象组合来调用被适配者代码时,被称为对象适配器。例如,上面显示的VendorAdapter是一个对象适配器,因为它创建了一个实例(对象组合)VendorAdaptee。