【设计模式】代理模式(Proxy)
目录
一、问题导入
二、实例剖析
三、代码实现(仅供参考)
四、结构成分:
五、优劣
1.优势
2.劣势
六、课件内容
1.为什么用(Why)
2.何时使用(When)
3.如何实现(How)
七、常见应用(非课程内容)
一、问题导入
买XX,就上XX!(广告位招租)
生活中,“代理”场景其实很常见 —— 比如买房时,屋主若不想直接与买家沟通,会委托房屋中介代为协商,中介此时就是屋主的"代理"。这种由一方代替另一方处理特定事务的逻辑,和我们接下来要讲的代理模式核心思路高度相似。下面,我们就从这个场景切入,详细介绍代理模式。
(这种代理有什么好处呢?屋主只需专注自身角色,不用懂营销;顾客也只需跟擅长营销的代理人沟通,到最终决定阶段,再通过代理人和屋主签订合同即可。)
二、实例剖析
在《我的世界》中,所有方块并非一开始就全部加载完成。当我们快速移动时,能明显看到远处的方块还没加载好,暂时没有渲染出来。这就对应了一个典型应用场景 —— 延迟加载。此时,我们可以让“代理人”来判断当前方块是否需要渲染:如果不需要,就先进行加载准备。这样一来,方块的渲染功能和控制渲染的逻辑就分离开了,每个部分的职责也更清晰。
其结构如下:

三、代码实现(仅供参考)
在实例代码当中,代理人CubeProxy自身持有can_render变量来控制服务接口Cube是否可以进行渲染。当实际服务调用被调用的时候,就需要通过代理人判断需否可以渲染该方块。
#pragma once#include<iostream>
#include<string>namespace _ProxyPattern
{//服务接口(方块)class Cube{public:virtual void on_render(int x){std::cout<<"方块"+std::to_string(x)<<"正在被渲染"<<std::endl;}};//代理(方块代理)class CubeProxy:public Cube{public:CubeProxy(Cube* cube) :cube(cube) {}void on_render(int x){if (can_render)cube->on_render(x);else{can_render = true;std::cout << "方块" + std::to_string(x) << "正在加载" << std::endl;}}private:Cube* cube;bool can_render = false;};//实际服务(渲染器)class Renderer{public:void render(Cube* cube){cube->on_render(1);}};void test(){Cube* cube = new Cube();CubeProxy* cubeProxy = new CubeProxy(cube);Renderer* renderer = new Renderer();renderer->render(cubeProxy);renderer->render(cubeProxy);//释放内存delete cube;delete cubeProxy;delete renderer;}
}
运行结果:

四、结构成分:
从实例剖析当中,我们可以抽象出其代理模式的组成:
(1)服务接口(Cube)
(2)实际服务(Renderer)
(3)代理(Proxy)
五、优劣
1.优势
(1)职责清晰
(代理负责控制访问,真实对象专注核心功能(如 Cube 只管渲染,CubeProxy 管加载判断))
(2)可扩展性强
(3)灵活性高
2.劣势
(1)访问效率较低
(2)可能需要开展更复杂的额外工作
六、课件内容
1.为什么用(Why)
(1)控制访问
(2)功能增强
2.何时使用(When)
(1)难以直接访问对象时
(密码门的密码锁🔒充当代理,只有通过密码锁🔒的测试才能访问门)
(2)直接访问对象会引发问题时
(资源没有加载的时候进行渲染,将会导致程序崩溃)
3.如何实现(How)
通过组合的方式添加中间对象
七、常见应用(非课程内容)
(1)延迟加载
(2)资源缓存
(3)权限控制
(4)远程代理
(5)智能代理
