基于springboot的美术馆管理系统的设计与实现(源码+lw+部署文档+讲解等)
2026/8/21 18:08:28
为另一个对象提供一个占位符或代理,以控制对真实对象的访问,在需要时才创建、加载或执行真实操作。
懒加载大图片:
不用代理,你会这样写:
ImagerealImage("huge_photo_100MB.raw");// 程序启动就加载,慢到吐!realImage.display();// 就算只看缩略图,也等半天| 项目 | 装饰器(Decorator) | 享元(Flyweight) | 外观(Facade) | 代理(Proxy) |
|---|---|---|---|---|
| 核心意图 | 动态叠加行为 | 共享内在状态节省内存 | 简化子系统接口 | 控制对真实对象的访问 |
| 持有的对象 | 1个(包装链) | 多个共享实例 | 多个子系统 | 1个(真实对象) |
| 接口一致性 | 完全一致 | 一致 | 简化版接口 | 完全一致(客户端无感) |
| 典型时机 | 运行时层层加 | 大量对象时共享 | 调用复杂系统时 | 延迟/控制/保护访问时 |
| 典型场景 | 流加密/日志 | 游戏树木/字符 | 视频转码 | 懒加载、远程代理、保护代理 |
| 口号 | “层层叠加” | “千物一面共享” | “一键搞定” | “替身先上,真身后到” |
#include<iostream>#include<memory>#include<string>usingnamespacestd;// 1. 统一图片接口classImage{public:virtual~Image()=default;virtualvoiddisplay()=0;virtualstringname()const=0;};// 2. 真实图片(加载很贵)classRealImage:publicImage{string filename;public:explicitRealImage(conststring&file):filename(file){loadFromDisk();// 真正昂贵的操作}private:voidloadFromDisk(){cout<<"[RealImage] 从磁盘/网络加载大图: "<<filename<<" (100MB)... 耗时5秒\n";// 模拟耗时加载:真实项目里这里读文件、解码等}public:voiddisplay()override{cout<<"[RealImage] 显示高清图: "<<filename<<endl;}stringname()constoverride{returnfilename;}};// 3. 代理图片(关键:懒加载 + 接口完全一致)classProxyImage:publicImage{string filename;unique_ptr<RealImage>realImage;// 真实对象,延迟创建public:explicitProxyImage(conststring&file):filename(file){cout<<"[ProxyImage] 创建代理(只存文件名,不加载)\n";}voiddisplay()override{if(!realImage){// 第一次使用才加载cout<<"[ProxyImage] 首次显示,触发懒加载...\n";realImage=make_unique<RealImage>(filename);}realImage->display();}stringname()constoverride{returnfilename;}};intmain(){// 创建10张图片代理(启动瞬间完成,几乎不耗内存)vector<unique_ptr<Image>>gallery;for(inti=1;i<=10;++i){gallery.push_back(make_unique<ProxyImage>("photo_"+to_string(i)+".raw"));}cout<<"\n=== 程序启动完成,用户开始浏览 ===\n\n";// 用户只看第1张时,才真正加载gallery[0]->display();// 再看第5张,又触发一次加载cout<<"\n用户翻到第5张...\n";gallery[4]->display();// 重复看第1张?秒开!因为已经缓存了cout<<"\n用户又回到第1张...\n";gallery[0]->display();}输出:
[ProxyImage] 创建代理(只存文件名,不加载) x10 === 程序启动完成,用户开始浏览 === [ProxyImage] 首次显示,触发懒加载... [RealImage] 从磁盘/网络加载大图: photo_1.raw (100MB)... 耗时5秒 [RealImage] 显示高清图: photo_1.raw 用户翻到第5张... [ProxyImage] 首次显示,触发懒加载... [RealImage] 从磁盘/网络加载大图: photo_5.raw (100MB)... 耗时5秒 [RealImage] 显示高清图: photo_5.raw 用户又回到第1张... [RealImage] 显示高清图: photo_1.raw ← 秒开!| 类型 | 作用 | 典型场景 |
|---|---|---|
| 虚代理 | 延迟加载(上面例子) | 图片/视频懒加载、大对象初始化 |
| 远程代理 | 代表网络另一端的对象 | RPC、WebService、分布式对象 |
| 保护代理 | 权限控制 | 只有管理员能调用某些方法 |
| 缓存代理 | 缓存结果 | 数据库查询结果缓存 |
| 智能引用 | 引用计数、日志 | 共享资源管理 |
“真身贵重别急造,代理先把活儿干;
需要之时再加载,内存速度两不耽!”
当你有一个“访问成本高昂的对象”(大文件、网络、权限控制),且不想每次都立即创建/加载时,
立刻上代理模式——用一个轻量替身控制访问,客户端完全无感,性能和资源双赢!
现在,结构型模式7种全部完结!
下一期正式进入行为型模式,第一篇是责任链模式(Chain of Responsibility)[13]。