大话设计模式C++版——代理模式
本篇开始前先发个福利,程杰的《大话设计模式》一书高清电子版(带目录)已上传至CSDN,免积分下载。
下载地址:http://download.csdn.net/detail/gufeng99/8843487
代理模式是一种比较简单但却实用的设计模式,他可以灵活的更换代理的对象,但保证功能的完整性,就如卖衣服的代理商,他可以代理美特斯邦威的衣服,如果美特斯邦威的衣服被大家吐槽不好卖了,他还可以换去代理卖佐丹奴的,但不管怎么更换,还是能满足大家的需求——买衣服。
下面以大话设计模式书中的例子为例,设计一个代理帮小明送花给小红。
1、依据接口编程,设计代理对象的接口
class IPursuit
{
public:
virtual ~IPursuit() {} virtual void SendFlowers() = 0;
};
2、代理类,也继承代理对象类,保持接口一致
class CProxy : public IPursuit
{
public:
CProxy() : m_poIPursuit(NULL) {}
~CProxy()
{
if (m_poIPursuit)
{
delete m_poIPursuit;
m_poIPursuit = NULL;
}
} void SetPursuit(IPursuit* poIPursuit)
{
//如果有旧的代理,要先删除,否则会造成内存泄漏
if (m_poIPursuit)
{
delete m_poIPursuit;
} m_poIPursuit = poIPursuit;
} void SendFlowers()
{
if (m_poIPursuit)
{
printf("Proxy help ");
m_poIPursuit->SendFlowers();
}
} private:
IPursuit* m_poIPursuit;
};
代理类实际上啥也没干,只是对同样的函数调用了一手被代理的对象的对应函数,当了一回二传手的角色。这里要注意代理对象由于会在代理中被释放,所以代理的对象一律必须是new出来的,即需在堆上创建的。
3、被代理对象类
class CPursuit : public IPursuit
{
public:
CPursuit(TString tstrName) : m_tstrName(tstrName) {}
~CPursuit() {} void SendFlowers()
{
_tprintf(_T("%s sent flowers to Xiaohong\n"), m_tstrName.c_str());
} private:
TString m_tstrName;
};
另附上TString宏
#ifdef UNICODE
#define TString std::wstring
#else
#define TString std::string
#endif
4、测试示例
void Test()
{
IPursuit* poIXiaoMing = new CPursuit(_T("XiaoMing"));
CProxy oCProxy; oCProxy.SetPursuit(poIXiaoMing);
oCProxy.SendFlowers();
}
5、代理类的应用
这个例子很形象,但却很难看出代理模式的应用和优点。实际上在《大话设计模式C++版——抽象工厂模式》中有一个操作数据库管理员工信息的例子,由于可能会在使用数据库的过程中切换数据库,如以前用的MySql,可能某个客户要求支持Access,这时就得进行切换了,此时用代理模式一样可以实现。
5.1 代理模式实现员工数据库管理类对数据库的切换
typedef struct Employee
{
int nID;
TString tstrName;
}; class IEmployee
{
public:
~IEmployee() {} virtual bool InserttoDB(Employee& stEmployee) = 0;
virtual Employee GetEmployee(int nID) = 0;
}; class CProxy : public IEmployee
{
public:
public:
CProxy() : m_poIEmployee(NULL) {}
~CProxy()
{
if (m_poIEmployee)
{
delete m_poIEmployee;
m_poIEmployee = NULL;
}
} void SetEmployee(IEmployee* poIEmployee)
{
if (m_poIEmployee)
{
delete m_poIEmployee;
} m_poIEmployee = poIEmployee;
} bool InserttoDB(Employee& stEmployee)
{
if (m_poIEmployee)
{
return m_poIEmployee->InserttoDB(stEmployee);
} return false;
} Employee GetEmployee(int nID)
{
if (m_poIEmployee)
{
return m_poIEmployee->GetEmployee(nID);
} Employee stEmployee;
return stEmployee;
} private:
IEmployee* m_poIEmployee;
}; class CEmployeefromMysql : public IEmployee
{
public:
bool InserttoDB(Employee& stEmployee)
{
_tprintf(_T("Insert employee %s into mysql\n"), stEmployee.tstrName.c_str());
return true;
} Employee GetEmployee(int nID)
{
Employee stEmployee;
printf("Get an employee from mysql by id %d\n", nID);
return stEmployee;
}
}; class CEmployeefromAccess : public IEmployee
{
public:
bool InserttoDB(Employee& stEmployee)
{
_tprintf(_T("Insert employee %s into access\n"), stEmployee.tstrName.c_str());
return true;
} Employee GetEmployee(int nID)
{
Employee stEmployee;
printf("Get an employee from access by id %d\n", nID);
return stEmployee;
}
};
5.2 使用示例
void DataBaseTest()
{
IEmployee* poIEmployee = new CEmployeefromMysql();
CProxy oCProxy; oCProxy.SetEmployee(poIEmployee); Employee stEmployee;
stEmployee.nID = 1;
stEmployee.tstrName = _T("Jim"); oCProxy.InserttoDB(stEmployee); //切换数据库对象
poIEmployee = new CEmployeefromAccess(); oCProxy.SetEmployee(poIEmployee);
oCProxy.InserttoDB(stEmployee);
}
从使用示例中就可以看出,代理类支持客户使用过程中动态切换数据库,这是和工厂模式最大的一点不同,特别适用于在经常需要切换类似对象模式的地方。
大话设计模式C++版——代理模式的更多相关文章
- 大话设计模式C++版——工厂模式在COM中的典型应用
上篇<大话设计模式C++版——抽象工厂模式>中,我们拯救世界未遂,留下小小的遗憾,本篇中我们将给出一个解决方案——COM组件技术,同时也顺便扯扯工厂模式在COM组件技术中的应用. 工厂模式 ...
- 大话设计模式Python实现-代理模式
代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = ...
- 大话设计模式C++版——建造者模式
日常做菜的过程中,经常会有忘记放盐或者放2次盐的经历,最后导致好好的一盘菜让大家无从下口.这个时候就需要用到建造者模式来规范炒菜的过程,来保证每一道菜都会经历加油.放食物.放盐.放味精这4道基本的工序 ...
- 大话设计模式C++版——抽象工厂模式
前面说过,简单工厂模式是最基础的一种设计模式,那以工厂命名的设计模式就是23种设计模式中最多的一种,他们一脉相承,一步一步进化而来,这里就是其中的最后一种——抽象工厂模式(Abstract Facto ...
- 大话设计模式C++版——工厂方法模式
工厂方法模式是以简单工厂模式为基础的,如果未了解简单工厂模式的同学可先浏览<大话设计模式C++版——简单工厂模式>.在简单工厂模式中,提到过简单工厂模式的缺陷,即违背了开发—封闭原则,其主 ...
- 大话设计模式C++版——简单工厂模式
简单工厂模式应该是所有设计模式中最简单,也最基础的一种模式,以下是一个简单的采用工厂模式写一个加减法的计算器. 1.抽象接口类——依赖倒转原则(高层和底层都要依赖于抽象,针对接口编程) class I ...
- 大话设计模式C++版——表驱动法改造简单工厂
上回<大话设计模式C++版——简单工厂模式>中指出了简单工厂模式的缺陷,即违背了开发—封闭原则,其主要原因是由于switch的判断结构的使用,使修改或添加新的对象时需要改动简单工厂类的代码 ...
- java设计模式之Proxy(代理模式)
java设计模式之Proxy(代理模式) 2008-03-25 20:30 227人阅读 评论(0) 收藏 举报 设计模式javaauthorizationpermissionsstringclass ...
- Java设计模式之《代理模式》及应用场景
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6525527.html 代理模式算是我接触较早的模式,代理就是中介,中间人.法律上也有代理, ...
随机推荐
- 20款响应式的 HTML5 网页模板【免费下载】
下面的列表集合了20款响应式的 HTML5 网页模板,这些专业的模板能够让你的网站吸引很多的访客.除了好看的外观,HTML5 模板吸引大家的另一个原因是由于其响应性和流动性.赶紧来看看. 您可能感兴趣 ...
- 微信中a链接无法进行跳转
[问题]微信页面开发时,各个主页之间的跳转,完全是通过a链接进行的,但是来回跳转几次,再次从其他主页面跳回首页的时候,微信头部出现了跳转加载进度条,但是就是不跳转,也没有任何反应 [范围]只出现在微信 ...
- CSS的盒子模型
1.边框:包裹内容的容器 统一设置:border: border-width border-style border-color 上:border-top 下:border-bottom 左:bord ...
- 3D打印公司网站dedecms大气模板
模板描述:1. 用FTP将安装包上传到服务器解压(或者解压在上传): 2. http://您的域名/install/ 进入到安装界面, 按照正常步骤安装即可:不要修改数据库表前缀,否则会造成原先数据无 ...
- gulp-babel 取消严格模式方法
最近项目决定用ES6语法重构,于是引入了gulp-babel去编译ES6. 问题来了,babel编译ES6会自动添加"use strict"在js文件的最前面,这就导致之前的项目文 ...
- CRM 2013 自动发送报表
Sql Server Report非常强大,导出不同格式的文档,比如work 或者excel都可以委托Reporting先做报表开发然后再在程序中调用生成指定格式的报表推送给用户,CRM也是集成了Re ...
- JSOM 中对各种字段操作
function createListItem() { var clientContext = new SP.ClientContext(_spPageContextInfo.siteAbs ...
- android键盘弹出头部上移处理
<ScrollView android:id="@+id/top_bar" android:layout_width="fill_parent" andr ...
- 腾讯bugly团队提供的android国内镜像
腾讯bugly团队提供的国内镜像 如果使用Android SDK Manager下载比较慢或者打不开,可以使用国内镜像 使用说明 http://android-mirror.bugly.qq.co ...
- git stash提交PR的正确步骤&git squash技术
1.git stash梳理 1.1git stash的克隆与同步 首先整理下git stash的逻辑是这样 在本地做出了新的修改,提交时显示当前的版本不是最新版本,这时就需要先pull一下自己代码仓库 ...