设计模式之 - 代理模式

一、定义

        我们去科技市场为自己的机器添加点奢侈的配件,很多 DIYer 都喜欢去找代理商,因为在代理商那里拿到的东西不仅质量有保证,而且价格和售后服务上都会好很多。客户通过代理商得到了自己想要的东西,而且还享受到了代理商额外的服务;而生产厂商通过代理商将自己的产品推广出去,而且可以将一些销售服务的任务交给代理商来完成(当然代理商要和厂商来共同分担风险,分配利润),这样自己就可以花更多的心思在产品的设计和生产上了。

        代理模式有两个英文名字: Proxy Pattern 和 Surrogate Pattern。代理模式的定义为:为其他对象提供一种代理以控制对这个对象的访问。说白了就是,在一些情况下客户不想或者不能直接引用一个对象,而代理对象可以在客户和目标对象之间起到中介作用,去掉客户不能看到的内容和服务或者增添客户需要的额外服务。

有四种常用的情况:(1)远程代理,(2)虚代理,(3)保护代理,(4)智能引用。

        考虑一个可以在文档中嵌入图形对象的文档编辑器。有些图形对象的创建开销很大。但是打开文档必须很迅速,因此我们在打开文档时应避免一次性创建所有开销很大的对象。这里就可以运用代理模式,在打开文档时,并不打开图形对象,而是打开图形对象的代理以替代真实的图形。待到真正需要打开图形时,仍由代理负责打开。

二、结构

        代理模式中的“代理商”要想实现代理任务,就必须和被代理的“厂商”使用共同的接口(你可以想象为产品)。于是代理模式就有三个角色组成了:

1) 抽象主题角色:声明了真实主题和代理主题的共同接口。

2) 代理主题角色:内部包含对真实主题的引用,并且提供和真实主题角色相同的接口。

3) 真实主题角色:定义真实的对象。

三、实现

 

#include <iostream>
#include <string>
using namespace std;

//抽象主题
class Image
{
public:
	Image(string name): m_imageName(name) {}
	virtual ~Image() {}
	virtual void Show() {}
protected:
	string m_imageName;
};

//真实主题
class BigImage: public Image
{
public:
	BigImage(string name):Image(name) {}
	~BigImage() {}
	void Show() { cout<<"Show big image : "<<m_imageName<<endl; }
};

//代理主题
class BigImageProxy: public Image
{
private:
	BigImage *m_bigImage;
public:
	BigImageProxy(string name):Image(name),m_bigImage(0) {}
	~BigImageProxy() { delete m_bigImage; }
	void Show() 
	{
		if(m_bigImage == NULL)
			m_bigImage = new BigImage(m_imageName);
		m_bigImage->Show();
	}
};

int main()
{
	Image *image = new BigImageProxy("proxy.jpg"); //代理
	image->Show(); //需要时由代理负责打开
	delete image;
	return 0;
}

四、总结

        代理模式能够协调调用者和被调用者,能够在一定程度上降低系统的耦合度。代理模式中的真实主题角色可以结合组合模式来构造,这样一个代理主题角色就可以对一系列的真实主题角色有效,提高代码利用率,减少不必要子类的产生。

与适配器模式的区别:

        适配器Adapter为它所适配的对象提供了一个不同的接口。相反,代理提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,因此,它的接口实际上可能只是实体接口的一个子集。

与装饰者模式的区别:

        尽管Decorator的实现部分与代理相似,但Decorator的目的不一样。Decorator为对象添加一个或多个功能,而代理则控制对对象的访问。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值