1. 程式人生 > >設計模式學習之Adapter模式

設計模式學習之Adapter模式

Adapter模式解決的問題在生活中經常遇到:比如我們有一個Team為外界提供S類服務,但是我們的Team裡面沒有能夠完成此項任務的member,然後我們得知有A可以完成這樣服務(把這項任務重新取了個名字叫S,並且不對外公佈他的實現),為了保證我們對外服務類別的一致性,可以通過兩種方案實現:

1)把A君直接招安到我們Team為我們工作,提供S服務的時候讓A君辦就是了;

2)A君可能在別的地方工作,並且不準備接收招安,於是可以想到用另一種方式進行解決:安排B君去完成這個任務,並做好工作,讓B君工作的時候可以向A君請教,因此B君就是一個複合體(提供S服務,但是是A君的繼承子弟);

實際上在軟體系統設計和研發中,這種問題也經常碰到:我們為了完成某項工作購買第三方庫來進行開發,這樣原先設計好的介面和第三方介面不一致,為了使這些介面不相容的類可以在一起工作,Adapter模式提供了將一個類的介面轉化為客戶希望的介面,Adapter模式通過2中類別實現:類模式和物件模式;

類模式實現程式碼為:

//Adapter.h

#ifndef _ADAPTER_H_
#define _ADAPTER_H_
class Target
{
public:
Target();
virtual ~Target();
virtual void Request();
protected:
private:
};
class Adaptee
{
public:
    Adaptee();
    ~Adaptee();
    void SpecificRequest();
protected:
private:
};
class Adapter:public Target,private Adaptee
{
public:
    Adapter();
    ~Adapter();
    void Request();
protected:
private:
};
#endif //~_ADAPTER_H_

//Adapter.cpp
#include "Adapter.h"
#include <iostream>
Target::Target()
{
}
Target::~Target()
{
}
void Target::Request()
{
    std::cout<<"Target::Request"<<std::endl;
}
Adaptee::Adaptee()
{
}
Adaptee::~Adaptee()
{
}
void Adaptee::SpecificRequest()
{
    std::cout<<"Adaptee::SpecificRequest"<<std::endl;
}
Adapter::Adapter()
{
}
Adapter::~Adapter()
{
}
void Adapter::Request()
{
    this->SpecificRequest();
}

//main.cpp
#include "Adapter.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
    Target *ptar = new Adapter();

    ptar->Request();
    return 0;
}

物件模式的實現程式碼為:

//Adapter.h
#ifndef _ADAPTER_H_
#define _ADAPTER_H_
class Target
{
public:

    Target();
    virtual ~Target();
    virtual void Request();
protected:
private:
};
class Adaptee
{
public:
    Adaptee();
    ~Adaptee();
    void SpecificRequest();
protected:
private:
};
class Adapter:public Target
{
public:
    Adapter(Adaptee* ade);
    ~Adapter();
    void Request();
protected:
private:
    Adaptee* _ade;
};
#endif //~_ADAPTER_H_ 

//Adapter.cpp
#include "Adapter.h"
#include <iostream>
Target::Target()
{
}
Target::~Target()
{
}
void Target::Request()
{
    std::cout<<"Target::Request"<<std::endl;
}
Adaptee::Adaptee()
{
}
Adaptee::~Adaptee()
{
}
void Adaptee::SpecificRequest()
{
    std::cout<<"Adaptee::SpecificRequest"<<std::endl;
}
Adapter::Adapter(Adaptee* ade)
{
    this->_ade= ade;
}
Adapter::~Adapter()
{
}
void Adapter::Request()
{
    _ade->SpecificRequest();
}

//main.cpp
#include "Adapter.h"
#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
    Adaptee* ade = new Adaptee;
    Target* adt = new Adapter(ade);
    adt->Request();
    return 0;
}

從Adapter模式程式碼中可以看到類模式的Adapter採用繼承的方式複用Adaptee的介面,而在物件模式的Adapter中我們採用組合的方式實現Adaptee的複用;在類模式中,通過private繼承Adaptee獲得實現繼承的效果,而通過public繼承Target獲得介面繼承的效果;

Adapter模式中存在介面繼承和實現繼承的區別和聯絡,介面繼承和實現繼承是面向物件領域的兩個重要概念,介面繼承指的是通過繼承子類獲得父類的介面,而實現繼承指的是通過繼承子類獲得父類的實現;在C++中public繼承既是介面繼承也是實現繼承,因為子類在繼承父類後既可以對外提供父類的介面操作,又可獲得父類的介面實現。