Adapter适配器模式

发布于:2025-05-19 ⋅ 阅读:(23) ⋅ 点赞:(0)

Adapter适配器模式是一种结构设计模式,用于解决接口不兼容的问题,通过适配器类,可以将一个类的接口转换为客户渴望的另一个接口,从而使原来无法协作的对象能够一起工作。

角色和职责:
目标接口(Target):定义客户希望使用的接口。
被适配者(Adaptee):需要适配的类或接口,其方法不符合客户的需求。
适配器(Adapter):实现目标接口

优点:
复用性:可以在不修改原有代码的情况下复用现有类。
灵活性:通过适配器,可以轻松支持新的接口或类。
符合开闭原则:扩展功能时,无需修改原有代码,只需增加新的适配器类。

缺点:
复杂性:增加了系统的复杂性,需要维护适配器类。
性能开销:适配器类可能会引入额外的性能开销。

应用场景:
第三方库集成:当需要使用第三方库但其接口不符合项目需求时,可以使用适配器模式。
旧系统改造:在改造旧系统时,可以使用适配器模式将旧接口适配为新接口。
不同数据库适配:在需要使用不同数据库时,可以通过适配器模式统一接口。

适配器模式从实现方式上可以分为两种:类适配器和对象适配器。它们的区别主要在于实现方法和适用情况的不同。

类适配器

定义:类适配器通过继承被适配类(Adaptee)并实现目标接口(Target)来实现适配。它利用继承关系,将被适配类的接口转换为目标接口。

实现方式:
适配器类直接继承被适配类。
适配器类实现目标接口,并重写目标接口中的方法,将调用转换为被适配类的方法调用。

优点:
直接继承被适配类,复用性强。
可以重定义被适配类的部分行为。

缺点:
由于继承关系,适配器类与被适配类之间耦合度较高,难以处理被适配类的子类。
不支持多个被适配类的适配,因为一个类只能继承一个父类。

适用场景:
需要复用被适配类的部分实现。
被适配类没有子类,或者适配器不需要处理被适配类的子类。

对象适配器

定义:对象适配器通过组合的方式,将被适配类(Adaptee)作为成员变量,并实现目标接口(Target)。它利用对象组合关系,动态地将被适配类的接口转换为目标接口。

实现方式:
适配器类包含一个被适配类的引用。
适配器类实现目标接口,并重写目标接口中的方法,将调用委托给被适配类的方法。

优点:
灵活性高,可以适配多个不同的被适配类。
支持被适配类及其子类的适配,因为组合关系不依赖于继承。
符合“合成复用原则”,即优先使用组合而不是继承。

缺点:
需要引入额外的引用,可能增加系统复杂性。
重定义被适配类的行为较为困难,需要定义被适配类的子类。

适用场景:
需要适配多个不同的被适配类。
被适配类有子类,且适配器需要处理这些子类。

在这里插入图片描述

类适配器模式

// 目标接口
class Target {
public:
    // 纯虚函数,模拟 Java 接口的抽象方法
    virtual void request() = 0;
    // 虚析构函数,确保正确释放派生类对象
    virtual ~Target() {}
};

// 被适配类
class Adaptee {
public:
    void specificRequest() {
        std::cout << "特殊请求" << std::endl;
    }
};

// 类适配器:继承Adaptee并实现Target接口
class ClassAdapter : public Adaptee, public Target {
public:
    // 实现Target接口的request方法
    void request() override {
        specificRequest();
    }
};

对象适配器模式

// 目标接口
class Target {
public:
    // 纯虚函数,模拟 Java 接口的抽象方法
    virtual void request() = 0;
    // 虚析构函数,确保正确释放派生类对象
    virtual ~Target() {}
};

// 被适配类
class Adaptee {
public:
    void specificRequest() {
        std::cout << "特殊请求" << std::endl;
    }
};

// 对象适配器:组合Adaptee并实现Target接口
class ObjectAdapter : public Target {
private:
    Adaptee* adaptee;
public:
    ObjectAdapter(Adaptee* adaptee) : adaptee(adaptee) {}
    // 实现Target接口的request方法
    void request() override {
        adaptee->specificRequest();
    }
    // 析构函数
    ~ObjectAdapter() {
        // 这里不删除 adaptee,因为它可能由外部管理
    }
};

网站公告

今日签到

点亮在社区的每一天
去签到