100、23种设计模式之适配器模式(9/23)

适配器模式(Adapter Pattern) 是一种结构型设计模式,它允许将不兼容的接口转换为客户端期望的接口,使原本由于接口不兼容而不能一起工作的类可以协同工作。

一、核心思想

  • 将一个类的接口转换成客户期望的另一个接口
  • 使原本因接口不匹配而无法一起工作的类能够一起工作
  • 属于"包装器"(Wrapper)设计模式的一种

二、适用场景

1.需要使用现有类,但其接口与需求不匹配
2.想要复用一些现有的子类,但这些子类缺少一些公共功能
3.需要与多个不兼容的接口或库一起工作

三、适配器模式在 C# 中的实现

1. 类适配器(使用继承)

csharp 复制代码
// 目标接口(客户端期望的接口)
public interface ITarget
{
    void Request();
}

// 被适配者(现有的不兼容类)
public class Adaptee
{
    public void SpecificRequest()
    {
        Console.WriteLine("Adaptee's SpecificRequest() called");
    }
}

// 类适配器(通过多重继承实现)
public class ClassAdapter : Adaptee, ITarget
{
    public void Request()
    {
        // 将目标接口方法转换为被适配者的方法
        base.SpecificRequest();
    }
}

// 客户端代码
class Program
{
    static void Main()
    {
        ITarget target = new ClassAdapter();
        target.Request(); // 输出: Adaptee's SpecificRequest() called
    }
}

2. 对象适配器(使用组合)

csharp 复制代码
// 目标接口
public interface ITarget
{
    void Request();
}

// 被适配者
public class Adaptee
{
    public void SpecificRequest()
    {
        Console.WriteLine("Adaptee's SpecificRequest() called");
    }
}

// 对象适配器(通过组合实现)
public class ObjectAdapter : ITarget
{
    private readonly Adaptee _adaptee;
    
    public ObjectAdapter(Adaptee adaptee)
    {
        _adaptee = adaptee;
    }
    
    public void Request()
    {
        // 将请求委托给被适配者
        _adaptee.SpecificRequest();
    }
}

// 客户端代码
class Program
{
    static void Main()
    {
        Adaptee adaptee = new Adaptee();
        ITarget target = new ObjectAdapter(adaptee);
        target.Request(); // 输出: Adaptee's SpecificRequest() called
    }
}

四、实际应用示例

示例:第三方支付系统适配

csharp 复制代码
// 目标接口(系统期望的支付接口)
public interface IPaymentGateway
{
    void ProcessPayment(decimal amount);
}

// 第三方支付系统(不兼容的接口)
public class ThirdPartyPaymentProcessor
{
    public void MakePayment(double amount)
    {
        Console.WriteLine($"Processing payment of amount: {amount}");
    }
}

// 适配器
public class PaymentAdapter : IPaymentGateway
{
    private readonly ThirdPartyPaymentProcessor _processor;
    
    public PaymentAdapter(ThirdPartyPaymentProcessor processor)
    {
        _processor = processor;
    }
    
    public void ProcessPayment(decimal amount)
    {
        // 将decimal转换为double以适应第三方系统
        double convertedAmount = (double)amount;
        _processor.MakePayment(convertedAmount);
    }
}

// 客户端代码
class Program
{
    static void Main()
    {
        var thirdPartyProcessor = new ThirdPartyPaymentProcessor();
        IPaymentGateway paymentGateway = new PaymentAdapter(thirdPartyProcessor);
        
        paymentGateway.ProcessPayment(99.99m);
        // 输出: Processing payment of amount: 99.99
    }
}

五、适配器模式的优缺点

优点

  • 单一职责原则:将接口转换代码从业务逻辑中分离
  • 开闭原则:可以引入新的适配器而不影响现有代码
  • 提高了类的复用性

缺点

  • 增加了系统复杂性(需要引入新的类和接口)
  • 在某些情况下,过度使用适配器会使系统变得难以维护

六、适配器模式与其他模式的关系

  • 与外观模式:适配器包装一个类,而外观模式包装整个子系统

  • 与桥接模式:两者都旨在将抽象与实现解耦,但适配器关注已有接口的兼容性,桥接模式关注提前设计

  • 与装饰器模式:适配器提供不同的接口,装饰器提供扩展功能而不改变接口

七、最佳实践

  • 当接口不兼容但功能相似时使用适配器模式
  • 优先使用对象适配器(组合方式)而非类适配器(继承方式),因为更灵活
  • 考虑使用依赖注入来管理适配器的生命周期
  • 为适配器编写单元测试以确保转换逻辑正确

适配器模式在C#中特别适用于集成遗留系统、第三方库或处理接口不匹配的情况,是构建可扩展、可维护系统的重要工具。

相关推荐
geovindu13 小时前
go: Strategy Pattern
开发语言·设计模式·golang·策略模式
嵌入式学习_force18 小时前
02_state
设计模式·蓝牙
qcx2321 小时前
Warp源码深度解析(七):Token预算策略——双轨计费、上下文溢出与摘要压缩
人工智能·设计模式·rust·wrap
Cosolar1 天前
提示词工程面试题系列 - Zero-Shot Prompting 和 Few-Shot Prompting 的核心区别是什么?
人工智能·设计模式·架构
geovindu2 天前
go:Template Method Pattern
开发语言·后端·设计模式·golang·模板方法模式
钝挫力PROGRAMER2 天前
贫血模型的改进
java·开发语言·设计模式·架构
qcx232 天前
Warp源码深度解析(二):自研GPU UI框架——WarpUI的ECH模式与渲染管线
人工智能·ui·设计模式·rust
qcx232 天前
Warp源码深度解析(三):Block-Based终端引擎——Grid模型、PTY与Shell Integration
人工智能·设计模式·架构·wrap
mounter6252 天前
Linux Kernel Design Patterns (Part 2):从经典链表到现代 XArray,拆解内核复杂数据结构的设计哲学
linux·数据结构·链表·设计模式·内存管理·kernel
rrr22 天前
【PyQt5】| 多线程设计模式
开发语言·qt·设计模式