一般模式:
class CHouseOwner
{
public:
CHouseOwner(CString strHouseAddress, CString strTeleNum, CString strName);
void SetPrice(int iPrice){//dosomething}
void Advertising(){//dosomething}
void TakeToSeeTheHouse(CHouseFinder houseFinder){//dosomething}
void TakeAgreeMent(){//dosomething}
}
class CHouseFinder
{
public:
CHouseFinder(CString strTeleNum, CString strName);
void BrowseAdvertising(CString& strName, CString& telNum);
void ContactWithHouseOwner(CString strName, CString strTeleNum);
void SeeTheHouse(CHouseOwner houseOwner);
void TakeAgreeMent();
}
void main()
{
CHouseOwner houseOwner("西二旗XX楼XX户","123456789", "小张");
houseOwner.SetPrice(2000);
houseOwner.Advertising();
CHouseFinder houseFinder("111111111", "小王");
CString strName,strTel;
houseFinder.BrowseAdvertising(strName,strTel);
houseFinder.ContactWithHouseOwner(strName,strTel);
houseOwner.TakeToSeeTheHouse(houseFinder);
houseFinder.SeeTheHouse(houseOwner);
houseOwner.TakeAgreeMent();
houseFinder.TakeAgreeMent();
}
- 代理模式:
中介机构出现以后,中介的职能之一就是作为房东出租房子的代理,对于只想收房租而不愿意做那些带人看房子之类的事的房东可以委托给中介机构代理: 类图:
普通代理
父类:
class CIHouseOwner
{
public:
void SetPrice(int iPrice){}
void Advertising(){}
void TakeToSeeTheHouse(CHouseFinder houseFinder){}
void TakeAgreeMent(){}
}
class CHouseProxy public CIHouseOwner
{
public:
CHouseProxy(CString strHouseAddress, CString strTeleNum, CString strName)
{
CHouseOwner* phouseOwner = new(strHouseAddress,strTeleNum, strName);
}
void SetPrice(int iPrice){phouseOwner->SetPrice(iPrice)}
void Advertising(){//dosomething}
void TakeToSeeTheHouse(CHouseFinder houseFinder){//dosomething}
void TakeAgreeMent(){phouseOwner->TakeAgreeMent()}
}
void main()
{
CHouseProxy houseProxy("西二旗XX楼XX户","123456789", "小张");
houseProxy.SetPrice(2000);
houseProxy.Advertising();
CHouseFinder houseFinder("111111111", "小王");
CString strName,strTel;
houseFinder.BrowseAdvertising(strName,strTel);
houseFinder.ContactWithHouseOwner(strName,strTel);
houseProxy.TakeToSeeTheHouse(houseFinder);
houseFinder.SeeTheHouse(houseProxy);
houseProxy.TakeAgreeMent();
houseFinder.TakeAgreeMent();
}
在该模式下,调用者(houseFinder)只知代理而不用知道真实的角色是谁,屏蔽了真实角色的变更对高层模块的影响,真实的主题角色想怎么修改就怎么修改,对高层次的模块没有任何影响,只要你实现了接口所对应的方法,该模式非常适合对扩展性要求较高的场合。在实际的项目中,一般都是通过约定来禁止new一个真实的角色。
强制代理
父类:
class CIHouseOwner
{
public:
void SetPrice(int iPrice){}
void Advertising(){}
void TakeToSeeTheHouse(CHouseFinder houseFinder){}
void TakeAgreeMent(){}
}
class CHouseProxy public CIHouseOwner
{
public:
CHouseProxy(CIHouseOwner* phouseOwner)
{
m_phouseOwner = phouseOwner;
}
void SetPrice(int iPrice){m_phouseOwner->SetPrice(iPrice)}
void Advertising(){//dosomething}
void TakeToSeeTheHouse(CHouseFinder houseFinder){//dosomething}
void TakeAgreeMent(){m_phouseOwner->TakeAgreeMent()}
}
class CHouseOwner public CIHouseOwner
{
public:
CHouseOwner(CString strHouseAddress, CString strTeleNum, CString strName);
void SetPrice(int iPrice)
{
if(IsProxy())
{
//dosomething
}
else
{
return;
}
}
void TakeAgreeMent()
{
if(IsProxy())
{
//dosomething
}
else
{
return;
}
}
CHouseProxy* GetProxy()
{CHouseProxy* pPorxy = new CHouseProxy(this); return pPorxy; }
private:
IsProxy(){//doSomething}
}
void main()
{
CHouseOwner houseOwner("西二旗XX楼XX户","123456789", "小张");
CHouseProxy* pHouseProxy = houseOwner.GetProxy();
houseProxy.SetPrice(2000);
houseProxy.Advertising();
CHouseFinder houseFinder("111111111", "小王");
CString strName,strTel;
houseFinder.BrowseAdvertising(strName,strTel);
houseFinder.ContactWithHouseOwner(strName,strTel);
houseProxy.TakeToSeeTheHouse(houseFinder);
houseFinder.SeeTheHouse(houseProxy);
houseProxy.TakeAgreeMent();
houseFinder.TakeAgreeMent(); }
强制代理的概念就是要从真实角色查找到代理角色,不允许直接访问真实角色。高层模块只要调用getProxy就可以访问真实角色的所有方法,它根本就不需要产生一个代理出来,代理的管理已经由真实角色自己完成。
代理模式定义
代理模式(Proxy Pattern)是一个使用率非常高的模式,定义如下: 为其他对象提供一种代理以控制对这个对象的访问。
- Subject抽象主题角色:抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。
-
RealSubject具体主题角色:也叫被委托角色、被代理角色。它是业务逻辑的具体执行者。
- Proxy代理主题角色:也叫委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
代理的另一种扩展
代理类不仅仅可以实现主题接口,也可以实现其他接口完成不同的任务。 如:
Class CProxy
{
public:
void Count();//收费
}
class CHouseProxy public CIHouseOwner,public CProxy
{
public:
CHouseProxy(CIHouseOwner* phouseOwner)
{
m_phouseOwner = phouseOwner;
}
void SetPrice(int iPrice){m_phouseOwner->SetPrice(iPrice)}
void Advertising(){//dosomething}
void TakeToSeeTheHouse(CHouseFinder houseFinder){//dosomething}
void TakeAgreeMent(){m_phouseOwner->TakeAgreeMent()}
void Count(){//dosomething}
}
代理模式的优点
- 职责清晰:真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的食物,通过后期的代理完成一件事务,附带的结果就是变成简洁清晰。
- 高扩展性:具体主题角色是随时都会发生变化的,只要它实现了接口,不管它如何变化,我们的代理类完全可以在不做任何修改的情况下使用。
- 智能化:动态代理
至少在以下集中情况下可以用 Proxy 模式解决问题:
1)创建开销大的对象时候,比如显示一幅大的图片,我们将这个创建的过程交给代理去完成,GoF 称之为虚代理(Virtual Proxy);
2)为网络上的对象创建一个局部的本地代理,比如要操作一个网络上的一个对象(网络性能不好的时候,问题尤其突出),我们将这个操纵的过程交给一个代理去完成, GoF 称之为远程代理(Remote Proxy);
3)对对象进行控制访问的时候,比如在Jive 论坛中不同权限的用户(如管理员、普通用户等)将获得不同层次的操作权限,我们将这个工作交给一个代理去完成,GoF 称 之为保护代理(Protection Proxy)。
4)智能指针(Smart Pointer),关于这个方面的内容,建议参看Andrew Koenig 的《C++第 52 页共 105 页 k_eckel设计模式精解-GoF 23 种设计模式解析附C++实现源 码http://www.mscenter.edu.cn/blog/k_eckel沉思录》中的第 5 章。