一、简介
Adapter 模式解决的问题是:应用程序中已经设计好了接口,但与这个第三方提供的接口不一致,为了使得这些接口不兼容的类(不能在一起工作)可以在一起工作,Adapter 模式提供了将一个类(第三方库)的接口转化为客户(购买使用者)希望的接口。Adapter设计模式就是为了应对这种“迁移的变化”。
Adapter模式有两种形式:类适配器模式和对象适配器模式。
1、类适配器模式
类适配器模式的 Adapter采用双继承的方式复用 Adaptee的的接口,从而获取SpecificRequest函数的访问权,实现功能的转换。类模式的结构图如下图:
多继承方式:
class Adapter : public Target, public Adaptee
{
public:
Adapter();
~Adapter();
void Request();
protected:
private:
};
2、对象适配器模式
对象适配器模式的 Adapter 采用组合的方式实现 Adaptee 的复用。在Adapter类中拥有一个Adaptee对象Adaptee *_ade,然后通过该对象_ade调用Adaptee类中的SpecificRequest函数,实现功能的转换。对象模式的结构图如下图:
定义对象方式:
class Adapter : public Target
{
public:
Adapter(Adaptee *ade);
~Adapter();
void Request();
protected:
private:
Adaptee *_ade;
};
二、详解
1、类适配器模式代码实现
(1)代码adapter_class.h:
#ifndef _ADAPTER_CLASS_H_
#define _ADAPTER_CLASS_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 Adaptee
{
public:
Adapter();
~Adapter();
void Request();
protected:
private:
};
#endif
(2)代码adapter_class.cpp:
#include <iostream>
#include "adapter_class.h"
using namespace std;
Target::Target()
{
}
Target::~Target()
{
}
void Target::Request()
{
cout<<"Target::Request"<<endl;
}
Adaptee::Adaptee()
{
}
Adaptee::~Adaptee()
{
}
void Adaptee::SpecificRequest()
{
cout<<"Adaptee::SpecificRequest"<<endl;
}
Adapter::Adapter()
{
}
Adapter::~Adapter()
{
}
void Adapter::Request()
{
cout<<"---Adapter interface---"<<endl;
this->SpecificRequest();
}
(3)代码main_class.cpp:
#include <iostream>
#include "adapter_class.h"
using namespace std;
int main()
{
Target *adt = new Adapter();
adt->Request();
delete adt;
adt = NULL;
return 0;
}
(4)makefile_class:
CFLAGS = -g
DEFINED = #-D _VERSION
LIBS =
CC = g++
INCLUDES = -I./
OBJS= main_class.o adapter_class.o
TARGET= main
all:$(TARGET)
$(TARGET):$(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS)
.SUFFIXES:.o .h
.SUFFIXES:.cpp .o
.cpp.o:
$(CC) $(DEFINED) -c $(CFLAGS) -o $@ $<
ok:
./$(TARGET)
clean:
rm -f $(OBJS) $(TARGET) core *.log
(5)centos6.3系统中运行结果:
2、对象适配器模式代码实现
(1)代码adapter_object.h:
#ifndef _ADAPTER_OBJECT_H_
#define _ADAPTER_OBJECT_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
(2)代码adapter_object.cpp:
#include <iostream>
#include "adapter_object.h"
using namespace std;
Target::Target()
{
}
Target::~Target()
{
}
void Target::Request()
{
cout<<"Target::Request"<<endl;
}
Adaptee::Adaptee()
{
}
Adaptee::~Adaptee()
{
}
void Adaptee::SpecificRequest()
{
cout<<"Adaptee::SpecificRequest"<<endl;
}
Adapter::Adapter(Adaptee *ade)
{
_ade = ade;
}
Adapter::~Adapter()
{
}
void Adapter::Request()
{
cout<<"---Adapter interface---"<<endl;
_ade->SpecificRequest();
}
(3)代码main_object.cpp:
#include <iostream>
#include "adapter_object.h"
using namespace std;
int main()
{
Adaptee *ade = new Adaptee();
Target *adt = new Adapter(ade);
adt->Request();
delete adt;
delete ade;
return 0;
}
(4)makefile_object:
CFLAGS = -g
DEFINED = #-D _VERSION
LIBS =
CC = g++
INCLUDES = -I./
OBJS= main_object.o adapter_object.o
TARGET= main
all:$(TARGET)
$(TARGET):$(OBJS)
$(CC) $(CFLAGS) -o $@ $(OBJS)
.SUFFIXES:.o .h
.SUFFIXES:.cpp .o
.cpp.o:
$(CC) $(DEFINED) -c $(CFLAGS) -o $@ $<
ok:
./$(TARGET)
clean:
rm -f $(OBJS) $(TARGET) core *.log
(5)
centos6.3系统中运行结果:
三、总结
(1)在Adapter模式的两种模式中,有一个很重要的概念就是接口继承和实现继承的区别和联系。接口继承和实现继承是面向对象领域的两个重要的概念,接口继承指的是通过继承,子类获得了父类的接口,而实现继承指的是通过继承子类获得了父类的实现(并不统共接口)。在C++中的public继承既是接口继承又是实现继承,因为子类在继承了父类后既可以对外提供父类中的接口操作,又可以获得父类的接口实现。当然我们可以通过一定的方式和技术模拟单独的接口继承和实现继承,例如我们可以通过private继承获得实现继承的效果(private继承后,父类中的接口都变为private,当然只能是实现继承了),通过纯抽象基类模拟接口继承的效果,但是在C++中pure virtual function也可以提供默认实现,因此这是不纯正的接口继承,但是在Java中我们可以interface来获得真正的接口继承了。
(2)在类模式 Adapter 中,通过 private 继承Adaptee 获得实现继承的效果,而通过 public 继承 Target 获得接口继承的效果。
(3)源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/8415943)。