打算去泰国旅行,可是办签证太麻烦啦,得自己去大使馆办理,可是自己又要工作,又不喜欢去搞这样的流程。怎么办呢?还好淘宝上有不少商家,可以代理你去办理,省去了不少的麻烦。只需要把你要办理的相关资料跟代理统一就行啦。
实际上签证代办,就是我们生活中使用到的代理模式。
什么是代理?抽象的讲就是:为其他对象提供一种代理以控制这这个对象的访问。
UML图
proxy: 保存一个realsubject的对象,并且提供与subject相同的接口对用户;提供删除和创建realsubject的功能;
subject: 定义realsubject和proxy的共用接口;
realsubject:proxy代理的实体;
代理模式的经典应用场景,便是c++的智能指针,c++指针容易导致内存泄漏,缺少垃圾回收一直为人诟病。
用只能指针(proxy)来实现指针(subject)的创建和删除,增加引用计数器提供智能回收。
#include <stdio.h>
#include <stdint.h>
#include <pthread.h>
#define SAFEDEL(p) if (p) {delete p;} p = NULL;
class prefCounter {
public:
prefCounter() {
m_ref = 0;
}
uint32_t add_ref() {
pthread_mutex_lock(&m_ref_addlock);
do {
if (m_ref == 0xffffffff) {
break;
}
m_ref++;
} while (0);
pthread_mutex_unlock(&m_ref_addlock);
return m_ref;
}
uint32_t dec_ref() {
pthread_mutex_lock(&m_ref_declock);
do {
if (m_ref == 0) {
break;
}
m_ref--;
} while (0);
pthread_mutex_unlock(&m_ref_declock);
return m_ref;
}
void reset() {
m_ref = 0;
}
uint32_t get_ref() {
return m_ref;
}
public:
uint32_t m_ref;
pthread_mutex_t m_ref_addlock;
pthread_mutex_t m_ref_declock;
};
template <class T>
class smartPtr {
public:
smartPtr(void)
: m_ptr(NULL) {
m_ref = new prefCounter();
m_ref->add_ref();
}
smartPtr(T *ptr)
: m_ptr(ptr) {
m_ref = new prefCounter();
m_ref->add_ref();
}
smartPtr(const smartPtr<T> &sp)
: m_ptr(sp.m_ptr)
, m_ref(sp.m_ref) {
m_ref->add_ref();
}
~smartPtr(void) {
dec_ref();
}
inline T& operator*() {
return *m_ptr;
}
inline T* operator->() {
return m_ptr;
}
uint32_t get_ref() {
return m_ref->get_ref();
}
smartPtr<T> & operator=(const smartPtr<T> &sp) {
if (this != &sp) {
printf("value[%d] operator= called and this is not self\n", *m_ptr);
dec_ref();
m_ptr = sp.m_ptr;
m_ref = sp.m_ref;
m_ref->add_ref();
}
return *this;
}
smartPtr<T> & operator=(T *ptr) {
if (m_ref && m_ref->dec_ref() == 0) {
dec_ref();
}
m_ptr = ptr;
m_ref = new prefCounter();
m_ref->add_ref();
return *this;
}
void attach(T *ptr){
}
T * detach() {
T *ptr = NULL;
if (m_ptr) {
ptr = m_ptr;
m_ptr = NULL;
m_ref->reset();
}
return ptr;
}
private:
void dec_ref(){
if (m_ref && m_ref->dec_ref() == 0) {
SAFEDEL(m_ref);
SAFEDEL(m_ptr);
}
}
private:
T *m_ptr;
prefCounter *m_ref;
};
上面的例子中smartPtr是一个代理类,而m_ptr才是真正的主体,指针使用的常用接口(*,->)都在smartPtr中提供了相应的接口。