C++设计模式八--AdapterPattern(适配器模式)

本文介绍了适配器模式的概念及其实现方式,包括对象适配器和类适配器的区别,以及如何通过适配器模式使得接口不兼容的类能够协同工作。并通过一个具体的火鸡适配器示例说明了其应用场景。

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

定义

  适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

要点

  1)当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器。
  2)适配器改变接口以符合客户的期望。
  3)适配器有两种形式:对象适配器类适配器。类适配器需要多重继承,故推荐使用对象适配器。
  4)适配器将一个对象包装起来以改变其接口;装饰者将一个对象包装起来以增加新的行为和责任;外观将一群对象“包装”起来以简化其接口。
  5)适配器允许客户使用新的库和子集合,无需改变“任何”代码。
  6)适配器可以适配多个类来提供一个接口,即可以有多个被适配者。

客户使用适配器的过程

  1.客户通过目标接口调用适配器的方法对适配器发出请求。
  2.适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口。
  3.客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用。

类图

这里写图片描述
Target:目标接口。
Adapter:适配器,实现目标接口,同时组合被适配者。这样被适配者的任何子类都可以搭配着适配器使用。
Adaptee:被适配者。

示例

  下面实现一个火鸡适配器。通过调用鸭子的方法能够调用到火鸡的方法。

Duck.h

#ifndef DUCK_H
#define DUCK_H

#include <iostream>
#include <string>

namespace adapter {

using std::string;
using std::cout;
using std::endl;

// 鸭子接口
class Duck
{
public:
    Duck(){}
    virtual ~Duck(){}
    virtual void quack() = 0;
    virtual void fly() = 0;
};

class RedDuck: public Duck
{
public:
    RedDuck(string n = "Red duck"): name(n)
    {
    }
    ~RedDuck(){}

    void quack()
    {
        cout << name << " is quacking" << endl;
    }
    void fly()
    {
        cout << name << " is flying" << endl;
    }
private:
    string name;
};
}
#endif

Turkey.h

#ifndef TURKEY_H
#define TURKEY_H

#include <iostream>
#include <string>

namespace adapter {

using std::string;
using std::cout;
using std::endl;

// 火鸡接口
class Turkey
{
public:
    Turkey(){}
    virtual ~Turkey(){}
    virtual void gobble() = 0;
    virtual void fly() = 0;
};

class WildTurkey: public Turkey
{
public:
    WildTurkey(string n): name(n)
    {
    }
    ~WildTurkey(){}

    void gobble()
    {
        cout << name << " is goobling" << endl;
    }
    void fly()
    {
        cout << name << " is flying" << endl;
    }
private:
    string name;
};
}

#endif

TurkeyAdapter.h

#ifndef TURKEY_ADAPTER_H
#define TURKEY_ADAPTER_H

#include "Duck.h"
#include "Turkey.h"

namespace adapter {

// 火鸡适配器
class TurkeyAdapter: public Duck
{
public:
    TurkeyAdapter(Turkey *t): turkey(t)
    {}
    ~TurkeyAdapter(){}
    void quack()
    {
        turkey->gobble();
    }
    void fly()
    {
        turkey->fly();
    }
private:
    Turkey *turkey;
};

}
#endif

main.cpp

#include "Duck.h"
#include "Turkey.h"
#include "TurkeyAdapter.h"

using namespace adapter;

int main()
{
    Turkey *wt = new WildTurkey("James");
    TurkeyAdapter *ta = new TurkeyAdapter(wt);

    ta->fly();
    ta->quack();

    delete ta;
    delete wt;

    return 0;
}

Makefile

CXX = g++
CFLAGS = -Wall
LDFLAGS = 

target = res
srcs = main.cpp
objs = $(srcs:.cpp=.o)
headers = $(wildcard *.h)


.PHONY: all
all: $(target)

$(target): $(objs) $(headers)
    $(CXX) $(LDFLAGS) -o $(target) $(objs)

$(objs):%.o:%.cpp
    $(CXX) $(CFLAGS) -c -o $@ $<

clean:
    rm -f $(target) *.o
测试

测试结果如下所示:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值