C++ 学习笔记(16)代理模式

代理模式的几种应用实例:

1. 远程代理

为远程程序在本地建立局部代理,可以隐藏外部资源存在于不同地址空间的事实,例如建立 agent 代理类处理 Socket 的数据发送与接收控制。生活中的典型例子还有有游戏代理服务器(加速器,远端计算机具有更优秀的计算能力和处理速度,加快响应和数据交互)。

2. 虚代理

延迟大型对象的构造。一开始只建立代理,一直到真正需要大型对象的时候才创建它,类似于 local static 对象。生活中的典型例子有快捷方式,直到点击应用程序才真正启动程序;浏览器解析图片,视频等大文件时,会采取延迟策略,优先显示文本和缩略图,直到用户需要完整图片和视频时才完整显示。

例子:快捷方式

#include <bits/stdc++.h>
#define rep( i , j , n ) for ( int i = int(j) ; i < int(n) ; ++i )
#define dew( i , j , n ) for ( int i = int(n-1) ; i > int(j) ; --i )
#define _PATH __FILE__ , __LINE__
typedef std::pair < int , int > P ;

namespace PROXY {
	// 基类提供接口
	class Source {
	public:
		virtual ~Source() = default;
		virtual void call() = 0;
		virtual void clear() = 0;
		virtual void display(std::string) = 0;
	} ;

	// 隐藏在代理对象背后真正的数据端
	class Application : public Source {
	private:
		// 该应用程序启动需要很多的资源
		std::vector<std::string> userData = { "YHL", "Fluence" };
	public:
		void call() override {
			std::cout << "真正的应用程序启动\n\n";
		}
		void clear() override {
			userData.clear();
			userData.shrink_to_fit();
		}
		void display(std::string picturePath) override {
			std::cout << "软件界面初始化...\n\n";
		}
	} ;

	// 客户直接操作“代理对象”, 逻辑端
	class App_proxy : public Source {
	private:
		std::shared_ptr<Application> ptr;
	public:
		// 直到真正需要应用程序 ( call ) 的时候才会构造
		void call() override {
			if(ptr == nullptr) 
				ptr = std::make_shared<Application>();
			std::cout << "点击快捷方式\n\n";
			ptr->call();
		} 
		void clear() override {
			// 前期准备工作, if 逻辑判断, 打日志, 线程加锁等

			ptr->clear();        // ------ 真正的数据实现

			// 后期清理工作, 日志记录, 线程解锁等
		}
		void display(std::string picturePath) override {
                // 根据应用程序是否启动而不同显示
			if(ptr != nullptr) {
				picturePath = ".../.../main_Picture";
				ptr->display(picturePath);
				return;
			}
			// 根据图片资源路径只显示快捷方式的图标......
			std::cout << "快捷方式图标初始化...\n\n";
		}
	} ;
}

int main () {
	PROXY::App_proxy proxy;
	// 一般情况下不启动, 但是有快捷方式
	proxy.display(".../.../...");

	// 直到大对象真正被需要的时候再创建
	proxy.call();
	proxy.display(".../.../...");
	return 0;
}

程序运行结果:

优点:

(1)代理类 App_proxy 和大对象 Application 拥有一样的接口,代理可以替代大对象的行为。       

(2)逻辑和实现分离,分文件时可以减低文件之间的编译依赖性。例如上述 clear 函数:

void clear() override {

	// 前期准备工作, if 逻辑判断, 打日志, 线程加锁等

	ptr->clear();        // ------ 真正的数据实现

	// 后期清理工作, 日志记录, 线程解锁等
}

(3)延迟生成大对象,直到真正被需要的时候才创建。

缺点:

(1)增加了一层间接访问

(2)如果大对象一定会被创建,会造成一个 shared_ptr 的损失,以及 virtual 机制的损耗(一个 vptr + 虚函数运行时查找)。

3. Pimpl

对象内含一个指针,指向另一个对象(另一个对象常常含真正的数据),就是所谓的 pimpl 手法——典型例子是 std::shared_ptr 等智能指针,代理类。

优点:

(1)方便实现引用计数。

(2)控制数据的建立,访问权限和销毁。

(3)逻辑和实现分离。

(4)大型对象赋值或者交换时只需要交换指针,提高效率。

4. Cache 代理

借鉴计算机高速缓存器的思想,将经常访问的数据(抑或是计算结果)缓存,以局部思想提高数据处理速度。

 

 

5. 动态代理模式

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值