c++/qt设计模式-适配器模式

文章中部分内容和思路来自《Head First设计模式》


模式定义

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


模式类图

1.对象适配器:

c++/qt设计模式-适配器模式

2.类适配器:

c++/qt设计模式-适配器模式

[ps:对象适配器和类适配器使用了两种不同的适配方式,对象适配器使用组合实现适配,类适配器使用继承实现适配]


典型案例

1.案例需求

不同国家的充电头和插座的设计标准不同,例如中国采用两孔扁平的插头和插座,而德国习惯使用三孔圆形插头。假设你只带了两孔扁平的插头去德国出差,而所住的旅馆只有三孔圆形的插头,设计一种方式不改变现有条件的情况下给手机充电。


2.情况分析

c++/qt设计模式-适配器模式

如图,我们需要一个额外的设备,该设备需要有两孔扁平插头的插孔(接口)同时也要有三孔圆形插头。


3.代码实现

-------------------

DBSocketInterface.h

-------------------

#ifndef DBSOCKETINTERFACE_H
#define DBSOCKETINTERFACE_H

class DBSocketInterface
{
public:
    virtual void powerByRound() = 0;
};

#endif // DBSOCKETINTERFACE_H

 

-------------------

GBSocketInterface.h

-------------------

#ifndef GBSOCKETINTERFACE_H
#define GBSOCKETINTERFACE_H

class GBSocketInterface
{
public:
    virtual void powerByFlat() = 0;
};

#endif // GBSOCKETINTERFACE_H

 

----------

DBSocket.h

----------

#ifndef DBSOCKET_H
#define DBSOCKET_H

#include "dbsocketinterface.h"

class DBSocket : public DBSocketInterface
{
public:
    DBSocket();

public:
    virtual void powerByRound();
};

#endif // DBSOCKET_H

 

------------

DBSocket.cpp

------------

#include "DBSocket.h"

#include <QDebug>

DBSocket::DBSocket()
{

}

void DBSocket::powerByRound()
{
    qDebug() << "power by round.";
}

 

----------

GBSocket.h

----------

#ifndef GBSOCKET_H
#define GBSOCKET_H

#include "GBSocketInterface.h"

class GBSocket : public GBSocketInterface
{
public:
    GBSocket();

public:
    virtual void powerByFlat();
};

#endif // GBSOCKET_H

 

------------

GBSocket.cpp

------------

#include "GBSocket.h"

#include <QDebug>

GBSocket::GBSocket()
{

}

void GBSocket::powerByFlat()
{
    qDebug() << "power by flat.";
}

 

-------

Hotel.h

-------

#ifndef HOTEL_H
#define HOTEL_H

#include "DBSocketInterface.h"

class Hotel
{
public:
    Hotel(DBSocketInterface *socket);

public:
    void powerForGBMobile(); // 给手机充电

public:
    DBSocketInterface *_dbSocket; // 只有圆头
};

#endif // HOTEL_H

 

---------

Hotel.cpp

---------

#include "Hotel.h"

Hotel::Hotel(DBSocketInterface *dbSocket)
{
    _dbSocket = dbSocket;
}

void Hotel::powerForGBMobile()
{
    _dbSocket->powerByRound(); // 看起来使用圆头充电
}

 

-------------------

Round2FlatAdaptor.h

-------------------

#ifndef ROUND2FLATADAPTOR_H
#define ROUND2FLATADAPTOR_H

#include "GBSocketInterface.h"
#include "dbsocketinterface.h"

class Round2FlatAdaptor : public DBSocketInterface
{
public:
    Round2FlatAdaptor(GBSocketInterface *gbSocket);

public:
    virtual void powerByRound();

private:
    GBSocketInterface *_gbSocket;
};

#endif // ROUND2FLATADAPTOR_H

 

---------------------

Round2FlatAdaptor.cpp

---------------------

#include "Round2FlatAdaptor.h"

Round2FlatAdaptor::Round2FlatAdaptor(GBSocketInterface *gbSocket)
{
    _gbSocket = gbSocket;
}

void Round2FlatAdaptor::powerByRound()
{
    _gbSocket->powerByFlat();
}


 

--------

main.cpp

--------

/**
 * 设计模式-适配器模式
 * 要点:1,已有接口(dbsocket) 2,目标接口(gbsocket) 3,适配器(与已有接口有共同超类,实现依赖目标接口)
 */
#include <QCoreApplication>

#include "Hotel.h"
#include "GBSocket.h"
#include "Round2FlatAdaptor.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    GBSocket socket;
    Hotel hotel(new Round2FlatAdaptor(&socket)); // Hotel hotel; hotel.setSocket(dbSocket);
    hotel.powerForGBMobile();

    return a.exec();
}