【设计模式】【结构型模式】适配器模式-Adaptor/Wrapper

由于网络上介绍设计模式的文章要么废话太多不讲要领,要么太细致入微,没有精力看,一番挣扎后,把比较好的介绍放在【设计模式】系列进行精要总结,以C++代码为例。文档内容主要参考《深入设计模式》一书。所有设计模式均可先看意图和示例代码。
本文介绍结构型模式之-适配器模式

意图

适配器模式是一种结构型设计模式, 它能使接口不兼容的对象能够相互合作。
适配器示意

应用场景

1. 希望使用某个类或功能,但其接口与已有框架代码不兼容时,可以使用适配器类

比如C++工程中希望调用sqlite3的接口,可以实现这样一个类SqliteService,封装sql语句,提供给上层业务调用。

实现方式

可看过示例代码后再回头读

  1. 确保至少有两个类的接口不兼容:
  • 一个无法修改 (通常是第三方、 遗留系统或者存在众多已有依赖的类) 的功能性服务类。
  • 一个或多个将受益于使用服务类的客户端类。
  1. 声明客户端接口, 描述客户端如何与服务交互。
  2. 创建遵循客户端接口的适配器类。 所有方法暂时都为空。
  3. 在适配器类中添加一个成员变量用于保存对于服务对象的引用。 通常情况下会通过构造函数对该成员变量进行初始化, 但有时在调用其方法时将该变量传递给适配器会更方便。
  4. 依次实现适配器类客户端接口的所有方法。 适配器会将实际工作委派给服务对象, 自身只负责接口或数据格式的转换。
  5. 客户端必须通过客户端接口使用适配器。 这样一来, 你就可以在不影响客户端代码的情况下修改或扩展适配器。

代码示例

#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
class Adaptee{
private:
    const std::string string = "string from adptee";
public:
    // Adaptee() : string("This can only get from Adaptee!") {}
    ~Adaptee(){}
    std::string Request() const {
        return string;
    }
};

class ClientTarget{
public:
    virtual ~ClientTarget(){}
    virtual std::string Request() const {
        return "Request from ClientTarget, it's for client\n";
    }
};

class Adaptor : public ClientTarget{
private:
    Adaptee* adptee_;
public:
    Adaptor(Adaptee* adp):adptee_(adp){}

    virtual std::string Request() const override {
        std::string result = adptee_->Request();
        std::transform(result.begin(), result.end(), result.begin(),
        [](unsigned char c) { return std::toupper(c); }); //业务处理,全转为大写
        return result;
    }
};

void ClientCode(ClientTarget* target){
    std::cout<<target->Request()<<std::endl;
}

int main(){
    std::cout<<"Client can only cooperate with ClientTarget:\n";
    ClientTarget* normal_target = new ClientTarget();
    ClientCode(normal_target);

    std::cout<<"ClientCode cannot cooperate with Adaptee, but can work through by Adaptor\n";
    Adaptee* adaptee = new Adaptee();
    Adaptor* adaptor = new Adaptor(adaptee);
    ClientCode(adaptor);

    delete normal_target;
    delete adaptee;
    delete adaptor;
    return 0;
}

关于代码的意思,看一眼输出即明了:

Client can only cooperate with ClientTarget:
Request from ClientTarget, it's for client

ClientCode cannot cooperate with Adaptee, but can work through by Adaptor
STRING FROM ADPTEE

适配器模式较简单,不做更多说明。但工程中很常用。

相比其他知识点,设计模式更重在理解而非记忆,(八股文会被但不会用的一大堆)不易考察,但是是程序员的内功之一。

参考文献

【1】https://refactoringguru.cn/design-patterns/adapter

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
/home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/include/msgpack/v1/object.hpp:664:34: error: ‘void* memcpy(void*, const void*, size_t)’ copying an object of non-trivial type ‘struct msgpack::v2::object’ from an array of ‘const msgpack_object’ {aka ‘const struct msgpack_object’} [-Werror=class-memaccess] std::memcpy(&o, &v, sizeof(v)); ^ In file included from /home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/include/msgpack/object_fwd.hpp:17, from /home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/include/msgpack/v1/adaptor/adaptor_base_decl.hpp:14, from /home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/include/msgpack/adaptor/adaptor_base_decl.hpp:13, from /home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/include/msgpack/adaptor/adaptor_base.hpp:13, from /home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/include/msgpack/v1/object_decl.hpp:16, from /home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/include/msgpack/object_decl.hpp:14, from /home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/include/msgpack/object.hpp:13, from /home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/include/msgpack.hpp:10, from /home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/example/cpp03/stream.cpp:10: /home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master/include/msgpack/v2/object_fwd.hpp:23:8: note: ‘struct msgpack::v2::object’ declared here struct object : v1::object { ^~~~~~ cc1plus: all warnings being treated as errors make[2]: *** [example/cpp03/CMakeFiles/stream.dir/build.make:63:example/cpp03/CMakeFiles/stream.dir/stream.cpp.o] 错误 1 make[2]: 离开目录“/home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master” make[1]: *** [CMakeFiles/Makefile2:415:example/cpp03/CMakeFiles/stream.dir/all] 错误 2 make[1]: 离开目录“/home/AQTJClient/AQTJAuditClient/depends/msgpack-c-master”
07-20

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值