不得不说的结构型模式-适配器模式

适配器模式(Adapter Pattern)是结构型模式之一,它将一个类的接口转换成客户希望的另一个接口,从而使原本由于接口不兼容而不能一起工作的类能够协同工作。适配器模式包括对象适配器和类适配器两种实现方式。

 

在对象适配器中,适配器通过包装一个需要适配的对象来实现接口转换,它将需要适配的对象作为成员变量,同时实现目标接口。在客户端调用目标接口时,适配器会将调用委托给被适配的对象,并根据需要进行接口转换和适配。在类适配器中,适配器通过多重继承来实现接口转换,它继承需要适配的类和目标接口,同时重写目标接口中的方法来实现接口转换。

以下是一个使用对象适配器实现的适配器模式的示例代码:

// 需要适配的接口
class ITarget {
public:
    virtual void Request() = 0;
};

// 需要适配的类
class Adaptee {
public:
    void SpecificRequest() {
        std::cout << "Adaptee::SpecificRequest()" << std::endl;
    }
};

// 对象适配器
class Adapter : public ITarget {
public:
    Adapter(Adaptee* adaptee) : m_adaptee(adaptee) {}

    virtual void Request() override {
        std::cout << "Adapter::Request()" << std::endl;
        m_adaptee->SpecificRequest();
    }

private:
    Adaptee* m_adaptee;
};

int main() {
    Adaptee* adaptee = new Adaptee();
    ITarget* target = new Adapter(adaptee);
    target->Request();

    delete target;
    delete adaptee;

    return 0;
}

在这个示例代码中,我们需要将Adaptee类的SpecificRequest()方法适配成ITarget接口的Request()方法,我们定义了ITarget接口和Adaptee类,并在Adapter类中通过包装Adaptee对象来实现接口转换。在客户端中,我们通过创建Adaptee对象和Adapter对象,然后将Adapter对象传递给客户端,客户端就可以调用目标接口Request()方法来访问Adaptee对象的SpecificRequest()方法了。

适配器模式的实际应用非常广泛,例如在新旧系统的数据交换中,可能需要将一种数据格式转换成另一种数据格式,可以使用适配器模式来实现;在使用第三方库时,可能需要将第三方库的接口转换成自己的接口,可以使用适配器模式来实现;在复用旧代码时,可能需要将旧代码的接口转换成新的接口,可以使用适配器模式来实现。通过使用适配器模式,我们可以

复用现有代码和接口,避免修改原有代码和接口,从而减少风险。

适配器模式的好处包括:

  1. 适配器模式可以让两个原本不兼容的接口能够协同工作,提高代码的复用性和可维护性;
  2. 适配器模式可以避免修改原有的代码和接口,从而减少风险和工作量;
  3. 适配器模式可以将适配的代码和接口与客户端代码解耦,提高代码的灵活性和可扩展性。

适配器模式的缺点包括:

  1. 适配器模式可能会增加代码的复杂度,特别是在涉及多个适配器的情况下;
  2. 适配器模式可能会影响代码的性能,因为需要进行接口转换和适配;
  3. 适配器模式可能会隐藏原有代码和接口的缺陷和问题,需要谨慎使用。

适配器模式是一种非常有用的结构型设计模式,可以将两个不兼容的接口协同工作,提高代码的复用性和可维护性,同时也需要注意其可能带来的复杂度和性能问题。

下面我们用 C++ 代码来实现一个简单的适配器模式示例。

首先,我们定义一个目标接口 Target,包含一个输出字符串的纯虚函数 output()

class Target {
public:
    virtual ~Target() = default;
    virtual void output() const = 0;
};

接下来,我们定义一个已有的类 Adaptee,其中包含一个输出整数的函数 outputInteger()

class Adaptee {
public:
    void outputInteger() const {
        std::cout << "Output integer: " << 42 << std::endl;
    }
};

为了让 Adaptee 类能够与 Target 接口兼容,我们需要定义一个适配器类 Adapter,并继承自 Target 接口,同时包含一个指向 Adaptee 对象的指针:

class Adapter : public Target {
public:
    Adapter(const Adaptee* adaptee)
        : m_adaptee(adaptee) {
    }
    
    virtual void output() const override {
        m_adaptee->outputInteger();
    }

private:
    const Adaptee* m_adaptee;
};

在适配器的 output() 函数中,我们将调用 Adaptee 类的 outputInteger() 函数来实现输出整数的功能。

最后,我们可以通过如下代码来测试适配器模式的效果:

int main() {
    Adaptee adaptee;
    Target* target = new Adapter(&adaptee);

    target->output();

    delete target;
    return 0;
}

在这段测试代码中,我们首先创建了一个 Adaptee 类对象 adaptee,然后将其作为参数传递给了一个 Adapter 类对象 adapter,接着将 adapter 对象指针强制转换为 Target 接口指针,并通过该指针调用了 output() 函数。在运行时,output() 函数会调用 Adaptee 类的 outputInteger() 函数,最终输出整数 42。

总之,适配器模式可以帮助我们解决两个不兼容的接口之间的问题,提高代码的复用性和可维护性。在实际应用中,适配器模式经常被用于系统集成和接口转换等场景。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五百五。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值