设计模式系列漫谈之十 - 适配器模式
故事
随着追求者与日俱增,小雪已经成了一名众人追捧的情人。小雪的手机功能越来越强,也同时给从事外贸工作的小雪增加了很多便利。我想,不久的将来,经典Design Pattern必将制造出比“芙蓉姐姐”还要大红大紫的“模式小姐”。
可是,现在的小雪又遇到新的烦恼。前天的产品交易会上,小雪认识了一名来中国投资的日本商人。几个小时交谈,小雪的美丽、聪慧、善良给这名日本商人留下深刻的印象,并彼此留下了通讯方式。事后,小雪才想起她的手机不支持日文显示,怎么办呢?
我们建议,在不改变原来功能的基础上,增加一个能够把日文短信翻译成中文短信的功能,然后按照原来的方式进行发送。
适配器模式的解决方案
适配器模式,又成为包装模式(Wrapper),就是把一个类的接口包装客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作。适配器模式有类的适配器模式和对象的适配器模式两种。我将分别使用两种Adapter模式达到小雪的要求。
1) 类的Adapter模式,需要定义的角色:
目标角色(IJapanMessage):这是客户所期待的接口。
源角色(NOKIA、MOTOROLA、SANSUNG):需要适配的类。 实现代码见:设计模式系列漫谈之二 - 工厂方法模式
适配器角色(NOKIAAdapter、MOTOROLAAdapter、SANSUNGAdapter):把源接口转换成目标接口。这一角色必须是类,并且继承源角色类。
目标角色接口如下:
{
public interface IJapanMessage
{
void SendJapanMessage(object japanmsg);
}
}
适配器角色类如下:
{
public class NOKIAAdapter : NOKIA,IJapanMessage
{
public void SendJapanMessage(object japanmsg)
{
//把日文japanmsg翻译为中文msg
base.SendMessage(msg);
}
}
public class MOTOROLAAdapter : MOTOROLA,IJapanMessage
{
public void SendJapanMessage(object japanmsg)
{
//把日文japanmsg翻译为中文msg
base.SendMessage(msg);
}
}
public class SANSUNGAdapter : SANSUNG,IJapanMessage
{
public void SendJapanMessage(object japanmsg)
{
//把日文japanmsg翻译为中文msg
base.SendMessage(msg);
}
}
}
由于增加适配器角色,工厂类如下:
{
public class JapanMessageFactory
{
public static IJapanMessage CreateJapanMessage(string Type)
{
IJapanMessage message= null;
switch (Type)
{
case "NOKIA":
message = new NOKIAAdapter();
break;
case "MOTOROLA":
message = new MOTOROLAAdapter();
break;
case "SANSUNG":
message = new SANSUNGAdapter();
break;
}
return message;
}
}
}
客户端调用方法:
//发送日文短信
((IJapanMessage)message).SendJapanMessage("ありがとうございます");
2) 对象的Adapter模式
目标角色(IJapanMessage):这是客户所期待的接口。
源角色(NOKIA、MOTOROLA、SANSUNG):需要适配的类。 实现代码见:设计模式系列漫谈之二 - 工厂方法模式
适配器角色(NOKIAAdapter、MOTOROLAAdapter、SANSUNGAdapter):通过聚合方式包装(Wrap)源角色对象,实现源接口转换成目标接口。
目标角色接口同上
适配器角色如下:
{
public class NOKIAAdapter : IJapanMessage
{
private NOKIA _nokia;
public NOKIAAdapter(NOKIA nokia)
{
this._nokia=nokia;
}
public void SendJapanMessage(object japanmsg)
{
//把日文japanmsg翻译为中文msg
_nokia.SendMessage(msg);
}
public void SendMessage(object msg)
{
_nokia.SendMessage(msg);
}
}
public class MOTOROLAAdapter :IJapanMessage
{
private MOTOROLA _motorola;
public MOTOROLAAdapter(MOTOROLA motorola)
{
this._motorola=motorola;
}
public void SendJapanMessage(object japanmsg)
{
//把日文japanmsg翻译为中文msg
_motorola.SendMessage(msg);
}
public void SendMessage(object msg)
{
_motorola.SendMessage(msg);
}
}
public class SANSUNGAdapter : IJapanMessage
{
private SANSUNG _sansung;
public SANSUNGAdapter(SANSUNG sansung)
{
this._sansung=sansung;
}
public void SendJapanMessage(object japanmsg)
{
//把日文japanmsg翻译为中文msg
_sansung.SendMessage(msg);
}
public void SendMessage(object msg)
{
_sansung.SendMessage(msg);
}
}
}
由于增加适配器角色,工厂类实现如下:
{
public class JapanMessageFactory
{
public static IJapanMessage CreateJapanMessage(string Type)
{
IJapanMessage japanMessage= null;
switch (Type)
{
case "NOKIA":
japanMessage= new NOKIAAdapter(new NOKIA());
break;
case "MOTOROLA":
japanMessage= new MOTOROLAAdapter(new MOTOROLA());
break;
case "SANSUNG":
picture = new SANSUNGAdapter(new SANSUNG());
break;
}
return japanMessage;
}
}
}
客户端调用方法:
//发送日文彩信
message.SendJapanMessage ("ありがとうございます");
为了更能说明适配器模式,引用一个生活例子:我使用的Dell笔记本的输入电压是19.5V,但是我们生活电压一般为220V,那么我就必须用通过专用的笔记本电源把220V转换为19.5V,那么这个笔记本电源就是Adapter。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述