一、描述:
适配器模式,使用之处比较特殊,不属于常规设计模式,主要用于不同系统之间的处理。是将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。举个例子,
比如我们有一个 Team 为外界提供 S 类服务,但是我们 Team 里面没有能够完成此项人物的 member,然后我们得知有 A 可以完成这项服务(他把这项人物重新取了个名字叫 S’,并且他不对外公布他的具体实现)。为了保证我们对外的服务类别的一致性(提供 S 服务),我们有以下两种方式解决这个问题:
1)把 B 君直接招安到我们 Team 为我们工作,提供 S 服务的时候让 B 君去办就是了;
2)B 君可能在别的地方有工作,并且不准备接受我们的招安,于是我们 Team 可以想这样一种方式解决问题:我们安排 C 君去完成这项任务,并做好工作(Money:))让 A 君工作的时候可以向 B 君请教,因此 C 君就是一个复合体(提供 S 服务,但是是 B 君的继承弟子)。
实际上在软件系统设计和开发中,这种问题也会经常遇到:我们为了完成某项工作购买了一个第三方的库来加快开发。这就带来了一个问题:我们在应用程序中已经设计好了接口,与这个第三方提供的接口不一致,为了使得这些接口不兼容的类(不能在一起工作)可以在一起工作了,Adapter 模式提供了将一个类(第三方库)的接口转化为客户(购买使用者)希望的接口。
在上面生活中问题的解决方式也就正好对应了 Adapter 模式的两种类别:类模式和对象模式。
Adapter 模式典型的结构图为:
图 2-1:Adapter Pattern(类模式)结构图
的接口,而在对象模式的 Adapter 中我们则采用组合的方式实现 Adaptee 的复用。有关这些具体的实现和分析将在代码说明和讨论中给出。
二、实例:
“我”在 2004 年的时候带了一个项目,做一个人力资源管理,该项目是我们总公司发起的项目,公司一共有 700 多号人,包括子公司,这个项目还是比较简单的,分为三大模块:人员信息管理,薪酬管理,职位管理,其中人员管理这块就用到了适配器模式,是怎么回事呢?当时开发时明确的指明:人员信息简管理的对象是所有员工的所有信息,然后我们就这样设计了一个类图:
这个项目是 04 年年底投产的,运行到 05 年年底还是比较平稳的,中间修修补补也很正常,05 年年底不知道是那股风吹的,很多公司开始使用借聘人员的方式招聘人员,我们公司也不例外,从一个人力资源公司借用了一大批的低技术、低工资的人员,分配到各个子公司,总共有将近 200 号人,然后就找我们部门老大谈判,说要增加一个功能借用人员管理,老大一看有钱赚呀,一拍大腿,做!
我带人过去一调研,不是这么简单,人力资源公司有一套自己的人员管理系统,我们公司需要把我们使用到的人员信息传输到我们的系统中,系统之间的传输使用 RMI(Remote Method Invocation,远程对象调用)的方式,但是有一个问题人力资源公司的人员对象和我们系统的对象不相同呀,他们的对象是这样的:
人员资源公司是把人的信息分为了三部分:基本信息,办公信息和个人家庭信息,并且都放到了 HashMap中,比如人员的姓名放到 BaseInfo 信息中,家庭地址放到 HomeInfo 中,这咱不好说他们系统设计的不好,那问题是咱的系统要和他们系统有交互,怎么办?使用适配器模式,类图如下:
本人工程目录如下:
注释:
main(),主程序
IUserInfo,本系统内接口
CUserInfo,本系统内实现类
IOuterUser,外系统接口
COuterUser,外系统实现类
COuterUserInfo,本系统内适配类
说明:COuterUserInfo实现IUserInfo接口,将外部系统实现类COuterUser转换成本系统内的接口IUserInfo。使用外部数据跟使用本系统内部数据一样。
注意:COuterUserInfo继承了IUserInfo,如果同时继承了COuterUser则是类适配器。如果COuterUserInfo只是使用了COuterUser则是对象适配器。
代码:
本系统内接口:IUserInfo类
IUserInfo.h
#ifndef __Adapter__IUserInfo__
#define __Adapter__IUserInfo__
#include <iostream>
using std::string;
class IUserInfo {
public:
IUserInfo(void){}
virtual ~IUserInfo(void){}
virtual string GetUserName() = 0;
virtual string GetHomeAddress() = 0;
virtual string GetMobileNumber() = 0;
virtual string GetOfficeTelNumber() = 0;
virtual string GetJobPosition() = 0;
virtual string GetHomeTelNumber() = 0;
};
#endif /* defined(__Adapter__IUserInfo__) */
本系统内实现:UserInfo类
UserInfo.h
#ifndef __Adapter__UserInfo__
#define __Adapter__UserInfo__
#include <iostream>
#include "IUserInfo.h"
using std::string;
class CUserInfo :public IUserInfo
{
public:
CUserInfo(void);
~CUserInfo(void);
string GetUserName();
string GetHomeAddress();
string GetMobileNumber();
string GetOfficeTelNumber();
string GetJobPosition();
string GetHomeTelNumber();
};
#endif /* defined(__Adapter__UserInfo__) */
UserInfo.cpp
#include "UserInfo.h"
using std::cout;
using std::endl;
using std::string;
CUserInfo::CUserInfo(void)
{
}
CUserInfo::~CUserInfo(void)
{
}
string CUserInfo::GetUserName()
{
cout << "姓名叫做..." << endl;
return "0";
}
string CUserInfo::GetHomeAddress()
{
cout << "这里是员工的家庭地址..." << endl;
return "0";
}
string CUserInfo::GetMobileNumber()
{
cout << "这个人的手机号码是0000..." << endl;
return "0";
}
string CUserInfo::GetOfficeTelNumber()
{
cout << "办公室电话是..." << endl;
return "0";
}
string CUserInfo::GetJobPosition()
{
cout << "这个人的职位是BOSS..." << endl;
return "0";
}
string CUserInfo::GetHomeTelNumber()
{
cout << "员工的家庭电话是..." << endl;
return "0";
}
基本信息 :OuterUserBaseInfo
OuterUserBaseInfo.h
#ifndef __Adapter__OuterUserBaseInfo__
#define __Adapter__OuterUserBaseInfo__
#include <iostream>
using std::cout;
using std::endl;
using std::string;
class COuterUserBaseInfo
{
public:
COuterUserBaseInfo(void)
{
}
~COuterUserBaseInfo(void)
{
}
string GetUserName()
{
cout << "姓名叫做..." << endl;
return "0";
}
string GetMobileNumber()
{
cout << "这个人的手机号码是0001..." << endl;
return "0";
}
};
#endif /* defined(__Adapter__OuterUserBaseInfo__) */
办公信息 :OuterUserOfficeInfo类
OuterUserOfficeInfo.h
#ifndef __Adapter__OuterUserOfficeInfo__
#define __Adapter__OuterUserOfficeInfo__
#include <iostream>
using std::cout;
using std::endl;
using std::string;
class COuterUserOfficeInfo
{
public:
COuterUserOfficeInfo(void)
{
}
~COuterUserOfficeInfo(void)
{
}
string GetOfficeTelNumber()
{
cout << "办公室电话是..." << endl;
return "0";
}
string GetJobPosition()
{
cout << "这个人的职位是BOSS..." << endl;
return "0";
}
};
#endif /* defined(__Adapter__OuterUserOfficeInfo__) */
个人家庭信息:OuterUserHomeInfo
OuterUserHomeInfo.h
#ifndef __Adapter__OuterUserHomeInfo__
#define __Adapter__OuterUserHomeInfo__
#include <iostream>
using std::cout;
using std::endl;
using std::string;
class COuterUserHomeInfo
{
public:
COuterUserHomeInfo(void)
{
}
~COuterUserHomeInfo(void)
{
}
string GetHomeAddress()
{
cout << "这里是员工的家庭地址..." << endl;
return "0";
}
string GetHomeTelNumber()
{
cout << "员工的家庭电话是..." << endl;
return "0";
}
};
#endif /* defined(__Adapter__OuterUserHomeInfo__) */
外系统接口:IOuterUser类
IOuterUser.h
#ifndef __Adapter__IOuterUser__
#define __Adapter__IOuterUser__
#include <iostream>
#include "OuterUserBaseInfo.h"
#include "OuterUserHomeInfo.h"
#include "OuterUserOfficeInfo.h"
class IOuterUser {
public:
IOuterUser(void){}
~IOuterUser(void){}
virtual COuterUserBaseInfo * GetUserBaseInfo() = 0;
virtual COuterUserHomeInfo * GetUserHomeInfo() = 0;
virtual COuterUserOfficeInfo * GetUserOfficeInfo() = 0;
};
#endif /* defined(__Adapter__IOuterUser__) */
外系统实现:OuterUser
OuterUser.h
#ifndef __Adapter__OuterUser__
#define __Adapter__OuterUser__
#include <iostream>
#include "OuterUserBaseInfo.h"
#include "OuterUserHomeInfo.h"
#include "OuterUserOfficeInfo.h"
#include "IOuterUser.h"
class COuterUser:public IOuterUser
{
public:
COuterUser(void)
{
}
~COuterUser(void)
{
}
COuterUserBaseInfo * GetUserBaseInfo();
COuterUserHomeInfo * GetUserHomeInfo();
COuterUserOfficeInfo * GetUserOfficeInfo();
};
#endif /* defined(__Adapter__OuterUser__) */
OuterUser.cpp
#include "OuterUser.h"
COuterUserBaseInfo * COuterUser::GetUserBaseInfo()
{
return new COuterUserBaseInfo();
}
COuterUserHomeInfo * COuterUser::GetUserHomeInfo()
{
return new COuterUserHomeInfo();
}
COuterUserOfficeInfo * COuterUser::GetUserOfficeInfo()
{
return new COuterUserOfficeInfo();
}
本系统内适配类:OuterUserInfo
OuterUserInfo.h
#ifndef __Adapter__OuterUserInfo__
#define __Adapter__OuterUserInfo__
#include <iostream>
#include "IUserInfo.h"
#include "OuterUser.h"
using std::string;
class COuterUserInfo :
public IUserInfo
{
public:
COuterUserInfo(void);
~COuterUserInfo(void);
string GetUserName();
string GetHomeAddress();
string GetMobileNumber();
string GetOfficeTelNumber();
string GetJobPosition();
string GetHomeTelNumber();
private:
COuterUser *m_pOuterUser;
};
#endif /* defined(__Adapter__OuterUserInfo__) */
OuterUserInfo.cpp
#include "OuterUserInfo.h"
COuterUserInfo::COuterUserInfo(void)
{
m_pOuterUser = new COuterUser();
}
COuterUserInfo::~COuterUserInfo(void)
{
delete m_pOuterUser;
}
string COuterUserInfo::GetUserName()
{
COuterUserBaseInfo *pBaseInfo = m_pOuterUser->GetUserBaseInfo();
pBaseInfo->GetUserName();
delete pBaseInfo;
pBaseInfo = NULL;
return "0";
}
string COuterUserInfo::GetHomeAddress()
{
COuterUserHomeInfo *pHomeInfo = m_pOuterUser->GetUserHomeInfo();
pHomeInfo->GetHomeAddress();
delete pHomeInfo;
pHomeInfo = NULL;
return "0";
}
string COuterUserInfo::GetMobileNumber()
{
COuterUserBaseInfo *pBaseInfo = m_pOuterUser->GetUserBaseInfo();
pBaseInfo->GetMobileNumber();
delete pBaseInfo;
pBaseInfo = NULL;
return "0";
}
string COuterUserInfo::GetOfficeTelNumber()
{
COuterUserOfficeInfo *pOfficeInfo = m_pOuterUser->GetUserOfficeInfo();
pOfficeInfo->GetOfficeTelNumber();
delete pOfficeInfo;
pOfficeInfo = NULL;
return "0";
}
string COuterUserInfo::GetJobPosition()
{
COuterUserOfficeInfo *pOfficeInfo = m_pOuterUser->GetUserOfficeInfo();
pOfficeInfo->GetJobPosition();
delete pOfficeInfo;
pOfficeInfo = NULL;
return "0";
}
string COuterUserInfo::GetHomeTelNumber()
{
COuterUserHomeInfo *pHomeInfo = m_pOuterUser->GetUserHomeInfo();
pHomeInfo->GetHomeTelNumber();
delete pHomeInfo;
pHomeInfo = NULL;
return "0";
}
主程序:main
main.cpp
#include <stdio.h>
#include "IOuterUser.h"
#include "IUserInfo.h"
#include "UserInfo.h"
#include "OuterUserInfo.h"
void DoIt()
{
IUserInfo *pYourGirl = new CUserInfo();
for (int i = 0; i<101; i+=20)
{
pYourGirl->GetMobileNumber();
}
delete pYourGirl;
}
void NowDoIt()
{
IUserInfo *pYourGirl = new COuterUserInfo();
for(int i = 0; i < 101; i += 20)
{
pYourGirl->GetMobileNumber();
}
delete pYourGirl;
}
int main(int argc, const char * argv[])
{
DoIt();
NowDoIt();
// insert code here...
printf("Hello, World!\n");
return 0;
}
结果如下:
参考文献:《设计模式之禅》,《GoF_23种设计模式解析》
参考博客:http://www.cnblogs.com/wanggary/archive/2011/04/13/2015335.html