概述
适配器模式、装饰器模式、代理模式和外观有些类似,又有些不同,他们的实现形式差不多,都是对已有的方法和类进行封装,以实现适配、增强、加以控制或隐藏系统复杂性的目的。
1 适配器模式
例如多功能读卡器,可插入多种不同的卡,完成读取数据的功能,但一定要实现一个统一的接口,使得不同的输入,能够产品相同的输出。
class CardReader{
public:
virtual void read()=0;
virtual bool accepted_datatype(string datatype)=0;
}
class Card1_Reader:public CardReader{
public:
void read(){
std::cout<<"read card1 data!";
}
bool accepted_datatype(string datatype){
if(datatype="card1_data")
return true;
return false;
}
}
class Card2_Reader:public CardReader{
public:
void read(){
std::cout<<"read card2 data!";
}
bool accepted_datatype(string datatype){
if(datatype="card2_data")
return true;
return false;
}
}
class Adapter{
public:
void read(string datatype){
for(auto& k: readers){
if(k->accepted_datatype(datatype))
k->read()
}
}
void add_reader(CardReader* reader){
readers.push_back(reader);
}
private:
std::vector<CardReader*> readers
}
以上写得比较简单,核心思想基本就是这样了。
2 装饰器模式
顾名思义,对某种东西进行装饰,使其在原有基础上有一些新的特性,因此,装饰器在构造时必须传入一个该类对象进去,它只起到装饰作用,例如:
class Item {
public:
virtual oid readinfo()=0;
}
class Box : public Item {
public:
void readinfo(){
std::cout<<"I'm a box";
}
}
class RedItem : public Item {
public:
RedItem(Item *box) : box_(box){}
void readinfo(){
box_->readinfo();
std::cout<<",and I'm red";
}
private:
Item *box_;
}
3 代理模式
与装饰器模式的实现非常接近,但主要用于对已有的东西的接口进行控制,使其在原有基础上更加完善,不易被误用等功能,此外,一般认为它与装饰器模式的一大区别在于构造时不需要传入该类对象,而是固定绑定某个对象上,例如:
class File {
public:
virtual oid readinfo()=0;
}
class VirtualFile : public File{
public:
void load(){
std::cout<<"file load from disk...";
}
}
class ProxyVirtualFile : public File {
public:
void load(){
if(loaded)
std::cout<<"file has been loaded!";
else{
file.load();
loaded=true;
}
}
private:
VirtualFile file;
bool loaded=false;
}
4 外观模式
提供一个简洁的接口供外部使用,把内部实现进行封闭,这样即使有内部的代码和功能修改外部也不会察觉,更利于用户的使用:
class HardWare{
public:
virtual void initial()=0;
}
class CPU:public HardWare{
public:
void initial(){
std::cout<<"initial CPU...!";
}
}
class Memory:public HardWare{
public:
void initial(){
std::cout<<"initial memory...!";
}
}
class computer{
public:
void initial(){
cpu.initial();
memory.initial();
}
private:
CPU cpu;
Memory memory;
}
以上几种形式比较类似,只是目的不同,此外也可以用继承来实现。