C#适配器模式实战:类适配与对象适配结构解析
在软件架构开发中,当需要复用现有第三方库或旧系统接口,但其定义的方法与当前系统需求不一致时,适配器模式提供了有效的解决方案。它通过在客户端目标接口与被适配者之间增加中间层,实现接口转换,使原本因接口不匹配而无法协同工作的类能够一起工作。
适配器模式的核心结构与原理
适配器模式的本质在于“转换”。正如生活中手机充电器将220V交流电转换为手机所需的低压直流电一样,代码层面的适配器负责将源接口转换为客户端期望的目标接口。
第1步:实现类适配器结构(Class Adapter)
类适配器模式使用C#的单继承机制实现。适配器类直接继承自被适配者类(Adaptee)并实现目标接口(ITarget)。这种方式利用多态性,但受限于单一继承的限制。
1. 定义目标接口与被适配者
首先定义客户端希望调用的统一接口 ITarget.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
public interface ITarget
{
void Request();
}
}
接着定义现有的、需要被适配的类 Adaptee.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
public class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()");
}
}
}
2. 创建适配器类
Adapter.cs 继承自 Adaptee 并实现 ITarget,内部调用父类方法完成适配:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
public class Adapter : Adaptee, ITarget
{
public void Request()
{
this.SpecificRequest();
}
}
}
3. 客户端调用验证
客户端无需知道具体的被适配者类型,仅通过目标接口调用:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
public class Client
{
static void Main(string[] args)
{
ITarget t = new Adapter();
t.Request();
}
}
}
运行输出结果证实接口已正确转换:
Called SpecificRequest()
请按任意键继续. . .
第2步:实现对象适配器结构(Object Adapter)
对象适配器模式采用组合而非继承。适配器类包含一个被适配者实例,通过转发请求来实现适配。这种方法灵活性更高,符合松耦合原则。
1. 完善目标与源结构
在此结构中,除了定义目标接口 ITarget.cs 和被适配者 Adaptee.cs 外,通常还需要一个默认实现的 Target 类供适配器继承,以覆盖方法:
// Target.cs (可选基类)
public class Target : ITarget
{
public virtual void Request()
{
Console.WriteLine("Called Target Request()");
}
}
2. 构建基于组合的适配器
Adapter.cs 继承自 Target,并持有 Adaptee 的私有实例,重写 Request 方法:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
public class Adapter : Target
{
private Adaptee _adaptee = new Adaptee();
public override void Request()
{
_adaptee.SpecificRequest();
}
}
}
3. 客户端调用
调用方式与类适配器一致:
static void Main(string[] args)
{
ITarget t = new Adapter();
t.Request();
}
第3步:实际业务场景演练(电源适配示例)
为了更直观理解,我们以“手机充电”为例。客户端(手机)期望获得特定电压,而电源提供220V高压,需要通过 Adapter 进行降压适配。
1. 定义电压获取接口与电源类
定义接口 ITarget.cs 和原始电源类 Power.cs:
// ITarget.cs
public interface ITarget { void GetPower(); }
// Power.cs
public class Power {
public void GetPower220V() { Console.WriteLine("从电源中得到220V的电压"); }
}
2. 编写适配器逻辑
在类适配器模式下,适配器继承 Power 并包装其功能:Adapter.cs
public class Adapter : Power, ITarget
{
public void GetPower()
{
this.GetPower220V(); // 获取220V
Console.WriteLine("得到手机的充电电压!"); // 模拟转换过程
}
}
3. 执行结果
通过 Client.cs 调用,控制台将打印出从220V高压转换为手机安全电压的过程信息。
适配器模式的深度比较与应用
优缺点与选型指南
- 类适配器(继承):优点是可以重新定义被适配者行为,且无需额外字段;缺点是 C# 不支持多重继承,只能适配一个类及其子类,且耦合度较高。
- 对象适配器(组合):优点是实现松耦合,只需引入一个对象实例,可以适配多个不同的被适配者类;缺点是需要额外的对象开销,重定义被适配者行为较困难。
建议:在大多数现代 C# 开发场景中,优先推荐使用对象适配器模式,因为它更符合面向对象设计的松耦合原则。
.NET Framework 中的实际应用
适配器模式并非仅仅存在于理论中,它在 .NET 生态系统中有着广泛而关键的落地:
- COM Interop(RCW):
.NET 程序无法直接操作旧的 COM 组件。.NET Framework 通过运行时生成的包装类 RCW(Runtime Callable Wrapper)作为适配器,将 COM 对象的接口转化为 .NET 对象模型,如下图所示:
- ADO.NET DataAdapter:
在进行数据库编程时,开发人员通常操作DataSet。而数据库读取的是流式数据,两者不匹配。DataAdapter起到了桥接作用,它从数据库查询数据,将其适配填充到DataSet中,实现了数据源的无关性。
以上就是适配器模式在C#语言中的详细内容,更多关于设计模式在实际项目中应用资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









