一. 定義
適配器模式將一個類的接口轉換成客戶希望的另外一個接口,使得原本由於接口不兼容而不能一起工作的那些類可以一起工作。
Adapter 模式的兩種類別:類模式和對象模式。
二. 舉例說明
實際中,我們為了完成某項工作購買了一個第三方的庫來加快開發。這個庫可能都是一些.dll文件,這就帶來了一個問題!我們在應用程序中已經設計好了接口,與這個第三方提供的接口不一致,為了使得這些接口不兼容的類(不能在一起工作)可以在一起工作了,Adapter模式提供了將一個類(第三方庫)的接口轉化為客戶(購買使用者)希望的接口的方法。
三. 代碼實現
類模式的Adapter采用繼承的方式復用Adaptee的接口。
[cpp] //目標類,可以想像成客戶所期代的接口
class Target
{
public:
Target()
{
}
virtual ~Target()
{
}
virtual void Request()
{
std::cout<<"Target::Request"<<std::endl;
}
};
//被適應者,可以看成 dll 提供的接口
class Adaptee
{
public:
Adaptee()
{
}
virtual ~Adaptee()
{
}
void SpecificRequest()
{
std::cout<<"Adaptee::SpecificRequest"<<std::endl;
}
};
//適配器類,通過在內部包裝被適應者對象 adaptee
//把源接口(SpecificRequest)轉換成目標接口(Request)
class Adapter: public Target, private Adaptee
{
public:
void Request()
{
this->SpecificRequest();
}
};
//測試代碼
int main(int argc,char* argv[])
{
Adaptee* ade = new Adaptee;
Target* adt = new Adapter;
adt->Request();
return 0;
}
//目標類,可以想像成客戶所期代的接口
class Target
{
public:
Target()
{
}
virtual ~Target()
{
}
virtual void Request()
{
std::cout<<"Target::Request"<<std::endl;
}
};
//被適應者,可以看成 dll 提供的接口
class Adaptee
{
public:
Adaptee()
{
}
virtual ~Adaptee()
{
}
void SpecificRequest()
{
std::cout<<"Adaptee::SpecificRequest"<<std::endl;
}
};
//適配器類,通過在內部包裝被適應者對象 adaptee
//把源接口(SpecificRequest)轉換成目標接口(Request)
class Adapter: public Target, private Adaptee
{
public:
void Request()
{
this->SpecificRequest();
}
};
//測試代碼
int main(int argc,char* argv[])
{
Adaptee* ade = new Adaptee;
Target* adt = new Adapter;
adt->Request();
return 0;
}
對象模式的Adapter中則采用組合的方式實現Adaptee的復用。
[cpp] //目標類 www.2cto.com
class Target
{
public:
virtual ~Target() {}
virtual void Request()
{
std::cout<<"Target::Request"<<std::endl;
}
};
//被適應類
class Adaptee
{
public:
virtual ~Adaptee() {}
void SpecificRequest()
{
std::cout<<"Adaptee::SpecificRequest"<<std::endl;
}
};
//適配器類,用於轉接兩者的接口
class Adapter:public Target
{
public:
Adapter(Adaptee* ade)
{
this->_ade= ade;
}
void Request()
{
_ade->SpecificRequest();
}
private:
Adaptee* _ade;
};
//測試代碼
int main(int argc,char* argv[])
{
Adaptee* ade = new Adaptee;
Target* adt = new Adapter(ade);
adt->Request();
return 0;
}
//目標類
class Target
{
public:
virtual ~Target() {}
virtual void Request()
{
std::cout<<"Target::Request"<<std::endl;
}
};
//被適應類
class Adaptee
{
public:
virtual ~Adaptee() {}
void SpecificRequest()
{
std::cout<<"Adaptee::SpecificRequest"<<std::endl;
}
};
//適配器類,用於轉接兩者的接口
class Adapter:public Target
{
public:
Adapter(Adaptee* ade)
{
this->_ade= ade;
}
void Request()
{
_ade->SpecificRequest();
}
private:
Adaptee* _ade;
};
//測試代碼
int main(int argc,char* argv[])
{
Adaptee* ade = new Adaptee;
Target* adt = new Adapter(ade);
adt->Request();
return 0;
}
四. 說明
1. 當接口不同時,首先不應該考慮用適配器,而是應該考慮通過重構統一接口。
2. 使用適配器模式是無奈之舉,通常在軟件開發後期或維護期再考慮使用。
作者 lwbeyond