包装器外观模式(Wrapper Facade)把现有的非面向对象的API所提供的函数和数据,封装在更加简洁的、健壮的、可移植的、可维护的和内聚的面向对象的类接口中。
一般通过两种方式实现跨平台:
1.用类似#ifdef宏的条件编译。
2.目录分离。如每个操作系统平台有自己的目录,包含与平台有关的包装器外观的实现。可使用语言处理工具在编译时从相关的目录中包含合适的包装器外观的实现类。
类图如下:
时序图:
例子:
#if defined(_WIN32)
#include <windows.h>
#else
#include <pthread.h>
#include <sys/errno.h>
#endif
class jmutex
{
public:
jmutex();
~jmutex();
void lock();
void unlock();
bool tryLock();
private:
void init(void);
#ifdef _WIN32
access
CRITICAL_SECTION criticalSection_;
#else
pthread_mutex_t hMutex_;
#endif
};
jmutex::jmutex()
{
init();
}
jmutex::~jmutex()
{
#ifdef _WIN32
DeleteCriticalSection(&criticalSection_);
#else
pthread_mutex_destroy(&hMutex_);
#endif
}
void jmutex::lock(void)
{
#ifdef _WIN32
EnterCriticalSection(&criticalSection_);
#else
pthread_mutex_lock(&hMutex_);
#endif
}
void jmutex::unlock(void)
{
#ifdef _WIN32
LeaveCriticalSection(&criticalSection_);
#else
pthread_mutex_unlock(&hMutex_);
#endif
}
bool jmutex::tryLock()
{
#ifndef WIN32
int error = pthread_mutex_trylock(&hMutex_); //EAGAIN
assert(error==0||error==EBUSY);
return (error==0);
#else
this->lock();
return true;
#endif
}
void jmutex::init(void)
{
#ifdef _WIN32
InitializeCriticalSection(&criticalSection_);
#else
int error = pthread_mutex_init(&hMutex_, 0);
assert(error==0);
#endif
}
包装器外观模式的优点:
1.具体的、内聚的和健壮的更高级面向对象的编程接口。
2.可移植性和可维护性好。
3.模块性、可复用性和可配置性强。
缺点:
1.功能丧失。当抽象阻止开发人员访问底层抽象的特定能力时,如开发人员在基于socket包装器类上想实现设置缓存区大小。
2.性能降低。多一层或几层函数调用。
3.编程语言和编译器的局限性。如集成C函数到类似smalltalk或java这样的语言时,就不存在可广为接受的标准。
参考《面向模式的软件体系结构:卷2》