设计模式之代理模式

发布于:2024-03-11 ⋅ 阅读:(56) ⋅ 点赞:(0)

设计模式专栏: http://t.csdnimg.cn/4Mt4u

目录

1.概述

2.结构

3.使用场景

4.实现

5.和适配器模式的区别

6.和装饰器模式的区别

7.总结


1.概述

        代理模式(Proxy Pattern)是一种结构型设计模式,它提供了对另一个对象的接口,以控制对这个对象的访问。代理模式的主要目的是在不改变原始对象代码的情况下,增加额外的操作或逻辑。

        在某些情况下,客户端代码不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。由代理对象向客户端提供引用原对象的接口,客户端通过调用代理对象访问原对象。

        代理这个词对我们来说非常熟悉,比如上网经常使用的代理服务器,还有销售代理商等。就是客户与目标之间的桥梁。若要为其他对象提供代理服务,那么首先本身也要具有与被代理对象同样的方法,那么这样在访问时才能真正起到(透明)代理的作用。所以代理类一般同被代理类是继承于同一个类的兄弟类,区别就是他是为别人服务的。

2.结构

        代理模式的UML类图如下:

角色定义:

抽象主题(Subject):  定义了真实主题和代理主题的共同接口,这样在任何使用真实主题的地方都可以使用代理主题。

真实主题(Real Subject): 实现了抽象主题接口,是代理对象所代表的真实对象。客户端直接访问真实主题,但在某些情况下,可以通过代理主题来间接访问。

代理(Proxy): 实现了抽象主题接口,并持有对真实主题的引用。代理主题通常在真实主题的基础上提供一些额外的功能,例如延迟加载、权限控制、日志记录等。

客户端(Client): 使用抽象主题接口来操作真实主题或代理主题,不需要知道具体是哪一个实现类。

3.使用场景

按职责来划分,通常有以下使用场景:

1.远程代理:也就是为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。这个不同的地址空间可以是在本机器上,也可以在另一台机器中。
2.虚拟代理:是根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象,使其只有在真正需要时才被创建。
3.安全代理:也叫保护代理,用来控制真实对象访问时的权限,如果有必要的话,可以给不同调用者提供不同的权限。
4.智能指引:是指当调用真实对象时,代理处理另外一些事,比如记录对此对象的调用次数等。
5.写时拷贝:虚拟代理的一种,把复制推迟到只有客户的需要时才进行。
6.缓存代理:为某一个目标的操作结果提供临时存储空间,以便其他客户的可以共享访问,有点缓存的味道。
7.防火墙代理:保护对象,不让用户访问,安全代理的特例。
8.同步代理:可以让几个用户同时访问同一个对象而不产生冲突。
前面四种代理方式比较常用。

4.实现

创建一个接口:

class ISubject
{
public:
	virtual void request() = 0;
};

创建实现接口的实体类:

class CRealSubject : public ISubject
{
public:
	void request() override {
		std::cout << "CRealSubject request..." << std::endl;
	}
};

class CProxySubject : public ISubject
{
public:
	explicit CProxySubject() : m_pRealSubject(new CRealSubject()) {}
	void request() override {
		std::cout << "CProxySubject request..." << std::endl;
		m_pRealSubject->request();
	}
private:
	std::unique_ptr<ISubject> m_pRealSubject;
};

测试示例:

int main()
{
    std::unique_ptr<ISubject> proxy(new CProxySubject());
	proxy->request();
    return 0;
};

输出:

CProxySubject request...
CRealSubject request...

5.和适配器模式的区别

设计模式之适配器模式-CSDN博客

        代理模式的主要目的是控制对对象的访问,它允许客户端通过代理对象间接地访问目标对象,以防止直接访问目标对象给系统带来不必要的复杂性。代理模式通常使用面向对象的继承或者组合方式实现,它适用于需要对对象进行控制和保护的情况,例如远程代理、虚拟代理等。

        适配器模式的主要目的是解决接口不匹配的问题,它通过将一个类的接口转换成客户希望的另一个接口,使原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式强调接口转换,它通常使用对象组合方式实现,适用于需要将一个类的接口转换成客户端期望的另一个接口的情况,例如旧系统的升级改造、不兼容接口的统一等。

总结来说,代理模式和适配器模式的主要区别在于:

1.应用场景不同:代理模式适用于需要对对象进行控制和保护的情况,而适配器模式适用于需要将一个类的接口转换成客户端期望的另一个接口的情况。
2.目的不同:代理模式的目标是通过代理对象控制对原对象的引用,防止直接访问目标对象给系统带来不必要的复杂性,而适配器模式的目标是通过适配器将一个类的接口转换成客户端期望的另一个接口。
3.实现方式不同:代理模式通常使用面向对象的继承或者组合方式实现,而适配器模式通常使用对象组合方式实现。  

6.和装饰器模式的区别

设计模式之装饰器模式-CSDN博客

        对装饰器模式来说,装饰者(decorator)和被装饰者(decoratee)都实现同一个 接口。对代理模式来说,代理类(proxy class)和真实处理的类(real class)都实现同一个接口。他们之间的边界确实比较模糊,两者都是对类的方法进行扩展,具体区别如下:

1.本质不同:装饰模式强调的是增强自身,在被装饰之后,你能够在被增强的类上使用增强后的功能,增强后你还是你,只不过能力更强了而已;代理模式强调要让别人帮你去做一些本身与你业务没有太多关系的职责,如记录日志、设置缓存。代理模式是为了实现对象的控制,因为被代理的对象往往难以直接获得或者是其内部不想暴露出来。
模式不同。装饰模式是以对客户端透明的方式扩展对象的功能,是继承方案的一个替代方案;代理模式则是给一个对象提供一个代理对象,并由代理对象来控制对原有对象的引用。
2.功能不同:装饰模式是为装饰的对象增强功能;而代理模式对代理的对象施加控制,但不对对象本身的功能进行增强。
3.关系不同:代理模式对被代理对象有控制权,可以选择执行或者不执行,而装饰模式是没有控制权的,但会新增一些装饰功能。
4.应用不同:代理模式可以很容易地在真实对象的方法前面或者后面加上自定义的方法,而装饰模式关注于在一个对象上动态地添加方法。
5.实现方式不同:代理模式在程序运行前,代理类编译的生成的.class文件就已经存在了,而动态代理是在程序运行时,通过反射机制动态创建而成。

7.总结

优点

1.解耦:代理模式能够解耦客户端和目标对象之间的直接交互,客户端只需要与代理对象交互,而个需要知道自标对象的体实现这有助于降低系统的耦合度,使得系统更加
灵活和可扩展。
2.增加额外的处理逻辑:代理对象可以在将请求传递给目标对象之前或之后:添加额外的处理逻辑。这可以用于实现一些特殊的功能,如访问控制、缓存、日志记录等
3.保护目标对象:代理模式可以保护目标对象,避免其被直接访问或暴露。这可以防证目标对象被恶意访问或修改,提高系统的安全性。

缺点

1.性能开销:由于需要在客户端和目标对象之间引入一个代理对象,这可能会增加一些性能开销。特别是在处理大量请求时,这种性能开销可能会更加明显。
2.代码复杂度增加:便用代理模式可能会增加系统的代码复杂度,因为需要额外编写代理对象的代码,并维护与目标对象之间的关系。

        总的来说,C++中的代理模式具有解耦、增加额外处理逻辅辑和保护目标对象等优点,但同时也可能带来性能开销和代码复杂度增加等缺点。在实际应用中,需要根据具体的需求和场景来权衡其优缺点,决定是否使用代理模式。

本文含有隐藏内容,请 开通VIP 后查看