设计模式之适配器模式 - 202202

适配器模式是一种设计模式,用于解决现有类接口与目标接口不兼容的问题,通过创建一个适配器类,将不兼容的接口转化为客户类期望的接口,从而实现接口的转换和代码的复用。此模式分为对象适配器和类适配器两种形式,可以作为类结构型模式或对象结构型模式使用。在C++实现中,适配器模式可以使用裸指针或智能指针来管理对象,确保资源的正确释放。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模式动机

  • 在软件开发中采用类似于电源适配器的设计和编码技巧被称为适配器模式。
  • 通常情况下,客户端可以通过目标类的接口访问它所提供的服务。有时,现有的类可以满足客户类的功能需要,但是它所提供的接口不一定是客户类所期望的,这可能是因为现有类中方法名与目标类中定义的方法名不一致等原因所导致的。
  • 在这种情况下,现有的接口需要转化为客户类期望的接口,这样保证了对现有类的重用。如果不进行这样的转化,客户类就不能利用现有类所提供的功能,适配器模式可以完成这样的转化。
  • 在适配器模式中可以定义一个包装类,包装不兼容接口的对象,这个包装类指的就是适配器(Adapter),它所包装的对象就是适配者(Adaptee),即被适配的类。
  • 适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。也就是说:当客户类调用适配器的方法时,在适配器类的内部将调用适配者类的方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类。因此,适配器可以使由于接口不兼容而不能交互的类可以一起工作。这就是适配器模式的模式动机。

模式定义

适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

模式结构

适配器模式包含如下角色:

  • Target:目标抽象类
  • Adapter:适配器类
  • Adaptee:适配者类
  • Client:客户类

适配器模式有对象适配器和类适配器两种实现:

对象适配器:

类适配器:

时序图

代码-裸指针版本

// Adapter.h 类声明
//
// Created by zhaoyf on 2022/4/10.
//

#ifndef CPPDESIGNPATTERN_ADAPTERPATTERN_H
#define CPPDESIGNPATTERN_ADAPTERPATTERN_H


namespace AdapterPattern {
    // Target
    class Target {
    public:
        virtual ~Target() {};

        virtual void Request() = 0;
    };

    // Adaptee
    class Adaptee {
    public:
        void SpecialRequest();
    };

    // Adapter
    class Adapter : public Target {
    public:
        Adapter(Adaptee *p);

        virtual ~Adapter() {};

        virtual void Request() override;

    private:
        Adaptee *ptee;
    };

    void test();
}


#endif //CPPDESIGNPATTERN_ADAPTERPATTERN_H
// Adapter.cpp 类定义
//
// Created by zhaoyf on 2022/4/10.
//

#include "AdapterPattern.h"
#include <iostream>

namespace AdapterPattern {
    // Adaptee
    void Adaptee::SpecialRequest() {
        std::cout << "Adaptee SpecialRequest" << std::endl;
    }

    // Adapter
    Adapter::Adapter(Adaptee *p) : ptee(p) {}

    void Adapter::Request() {
        ptee->SpecialRequest();
    }
}
// main.cpp 测试代码
    int main() {
        Adaptee *ptee = new Adaptee();
        Target *p = new Adapter(ptee);
        p->Request();

        delete ptee;
        delete p;
        return 0;
    }

output:
Adaptee SpecialRequest

代码-智能指针版本

// AdapterPattern_SharedPtr.h
//
// Created by zhaoyf on 2022/4/16.
//

#ifndef CPPDESIGNPATTERN_ADAPTERPATTERN_SHAREDPTR_H
#define CPPDESIGNPATTERN_ADAPTERPATTERN_SHAREDPTR_H

#include <memory>

namespace AdapterPattern_SharedPtr {
    // Target
    class Target {
    public:
        virtual ~Target() {};

        virtual void Request() = 0;
    };

    // Adaptee
    class Adaptee {
    public:
        void SpecialRequest();
    };

    // Adapter
    class Adapter : public Target {
    public:
        Adapter(std::unique_ptr<Adaptee> p);

        virtual ~Adapter() {};

        virtual void Request() override;

    private:
        std::unique_ptr<Adaptee> ptee;
    };
}


#endif //CPPDESIGNPATTERN_ADAPTERPATTERN_SHAREDPTR_H
// AdapterPattern_SharedPtr.cpp
//
// Created by zhaoyf on 2022/4/16.
//

#include "AdapterPattern_SharedPtr.h"
#include <iostream>

namespace AdapterPattern_SharedPtr {
    // Adaptee
    void Adaptee::SpecialRequest() {
        std::cout << "Adaptee SpecialRequest" << std::endl;
    }

    // Adapter
    Adapter::Adapter(std::unique_ptr<Adaptee> p) : ptee(std::move(p)) {}

    void Adapter::Request() {
        ptee->SpecialRequest();
    }
}
// main.cpp 测试代码
    int main() {
        std::unique_ptr<Target> pTarget = std::make_unique<Adapter>(std::make_unique<Adaptee>());
        pTarget->Request();

        return 0;
    }

output:
Adaptee SpecialRequest

站在别人的肩旁上,感谢,参考文章如下:

1. 适配器模式 — Graphic Design Patterns

https://github.com/JakubVojvoda/design-patterns-cpp/blob/master/adapter/ClassAdapter.cpp

个人代码仓库:

Cpp_Design_Pattern: 用C++实现的设计模式学习

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值