注:本文主要代码基于大话设计模式里的C#代码(第7章)。
UML图:
代理模式的实现:
代理模式很好实现,注意的是要将RealSubject要代理的功能抽象出一个Subject接口,
让Proxy代理类实现该接口,这样外界可以通过代理对象直接使用RealSubject的功能。
实体类可以将自己的不同功能代理出去,这样实体类只跟代理类耦合,外界只跟代理类耦合。
代理类相当于一个中介者。并可适当地添加或优化某些调用。
下面代码展示的是代理恋爱(@_@!)由于追求者使用代理人来实现自己送礼物的功能
被追求的女同学不需知道到底是谁在追求她,她只负责接收礼物。
代码如下:
/*****************************************************
* 模式名:代理模式
* 时间:2010.6.4
* -by gouki04
*****************************************************/
#pragma once
#include <string>
//
class cSchoolGirl; // 女学生类
class IGiveGift; // 送礼物接口
class cPursuit; // 追求者
class cProxy; // 代理类
//
// 女学生类
// 相当于client类
class cSchoolGirl
{
private:
std::string m_name; // 姓名
public:
std::string GetName() const { return m_name; }
void SetName(std::string name) { m_name = name; }
};
// 送礼物接口
// 相当于Subject类,定义了实体和代理的公共接口
class IGiveGift
{
public:
virtual std::string GiveDolls() = 0;
virtual std::string GiveFlowers() = 0;
virtual std::string GiveChocolate() = 0;
};
// 追求者
// 相当于RealSubject类,实际工作的类
class cPursuit : public IGiveGift
{
private:
cSchoolGirl * m_mm;
public:
cPursuit(cSchoolGirl* mm) : m_mm(mm) {}
std::string GiveDolls() { return m_mm->GetName() + std::string(" 送你洋娃娃"); }
std::string GiveFlowers() { return m_mm->GetName() + std::string(" 送你鲜花"); }
std::string GiveChocolate() { return m_mm->GetName() + std::string(" 送你巧克力"); }
};
// 代理类
// 即Proxy类,主要的功能是代理RealSubject接受外界的调用
// 使得减少了RealSubject与外界的耦合
class cProxy : public IGiveGift
{
private:
cPursuit * m_gg;
public:
cProxy(cSchoolGirl* mm) { m_gg = new cPursuit(mm); }
// 代理的时候可以添加一点额外的功能,例如多加一句“你好”
std::string GiveDolls() { return std::string("你好,") + m_gg->GiveDolls(); }
std::string GiveFlowers() { return std::string("你好,") + m_gg->GiveFlowers(); }
std::string GiveChocolate() { return std::string("你好,") + m_gg->GiveChocolate(); }
};
// 测试的main函数
// int main()
// {
// using namespace std;
//
// cSchoolGirl jiaojiao;
// jiaojiao.SetName("李娇娇");
//
// cProxy daili(&jiaojiao);
//
// cout<<daili.GiveDolls()<<endl;
// cout<<daili.GiveFlowers()<<endl;
// cout<<daili.GiveChocolate()<<endl;
//
// return 0;
// }