设计模式学习[6]---代理模式

news/2024/9/18 23:05:13 标签: 设计模式, 学习, 代理模式

文章目录

  • 前言
  • 1.原理阐述
  • 2.举例
    • 2.1 例子与类图
    • 2.2 代码
  • 总结

前言

代理这个词,从小到大听过不少。比如什么代理服务器,代理商,代理人之类的。通俗来说,代理无非无非就是我代表你处理事务的意思。

那么在设计模式中,针对类的操作,要代理执行其实也有这么一个模式,就是这篇博客要写的代理模式了。

1.原理阐述

代理模式:为其他对象提供一种代理以控制对这个对象的访问。

代理模式的原理如上所示,其本质上也就是在前言提到的,我代表你,处理事务。
在面向对象中,就是当前这个类(代理类),为其他对象提供一种代理,来控制这个对象访问。

代理模式都用在一些什么场合呢?

一般来说分为几种

第一种应用是远程代理,也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。当我在应用程序的项目中加入一个Web引用,引用一个WebService,此时会在项目中生成一个WebReference的文件夹和一些文件,其实它们就是代理,这就使得客户端程序调用代理就可以解决远程访问的问题。

第二种应用是虚拟代理,是根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象 。这样就可以达到性能的最优化,比如说你打开一个很大的HTML网页时,里面可能有很多的文字和图片,但你还是可以很快打开它,此时你所看到的是所有的文字,但图片却是一张一张地下载后才能看到。那些未打开的图片框,就是通过虚拟代理来替代了真实的图片,此时代理存储了真实图片的路径和尺寸。

第三种应用是安全代理,用来控制真实对象访问时的权限。一般用于对象应该有不同的访问权限的时候。第四种是智能指引,是指当调用真实的对象时,代理处理另外一些事。如计算真实对象的引用次数,这样当该对象没有引用时,可以自动释放它;或当第一次引用一个持久对象时,将它装入内存;或在访问一个实际对象前,检查是否已经锁定它,以确保其他对象不能改变它。它们都是通过代理在访问一个对象时附加一些内务处理。

代理模式其实就是在访问对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。
说白了,代理就是真实对象的代表。


2.举例

原理比较简单,下面结合一下具体代码例子来说明。

2.1 例子与类图

假如你要追一个女生,所以你给女孩子送礼物;但是你为人比较腼腆,你就找你的好朋友Tom帮你代送;那么你的好朋友就是你的代理。
这里简单分析一下类的关系,你就是追求者Pursuit,好朋友Tom是代理Proxy;喜欢的女孩子是目标类Target。
你向女孩子送礼物,借好朋友Tom之手,女孩子接受/拒绝。其实在这个关系里,如果Tom不说是你送的,女孩子很可能以为是Tom送的,最后人家女孩子喜欢上了Tom哈哈哈哈哈。

类图大体是这样
在这里插入图片描述

简单分析一下:因为Proxy是代理,所以对于代理者来说,要知道代理的对象是谁,所以这里Proxy类有一个Pursuit的成员变量。

为什么这里要有一个送礼接口?这里其实是之前介绍过的依赖倒置的一个用法。Pursuit和Proxy两者之间耦合比较紧密,因为代理送礼物实际上是调用Pursuit去送,这里就有一个了类与类之间的耦合。那么采用依赖倒置的方式,就只需要关注接口的即可,具体实现交给具体类做。


2.2 代码

// PorxyMode.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
class IGiftOperation
{
public:
	virtual void GiveGift() = 0;
};
class Pursuit:public IGiftOperation
{
public:
	Pursuit() {};
	~Pursuit() {};
	void GiveGift()
	{
		std::cout << "Pursuit 送礼物" << std::endl;
	};
};
class Proxy :public IGiftOperation
{
public:
	Proxy() {};
	~Proxy() {};
	Proxy(Pursuit You)
	{
		you = You;
	}
	void GiveGift()
	{
		you.GiveGift();
	}
private:
	Pursuit you;
};
class Target
{
public:
	Target() {};
	~Target() {};
	void ReceiveGift()
	{
		std::cout << "Target 接收礼物" << std::endl;
	}

};
int main()
{
	Pursuit You;
	Proxy tom(You);
	Target girl;
	tom.GiveGift();
	girl.ReceiveGift();

	return 0;
}

这里代码有一个注意点,如果我Proxy的成员变量不是Pursuit的对象,而是指针。
但是我在Proxy的构造函数中,给Proxy传递的是一个Pursuit对象,同时取这个参数的地址,给到我的成员变量,再调用GiveGift函数。
此时编译能过,但是无法运行。

原因:
构造函数也是函数,函数有形参和实参这个说法,对于Proxy来说,传进来的Pursuit对象其实是实际对象的拷贝,是一个形参,虽然构造函数里面存了地址,但是函数结束后这个形参是会被释放的。所以在调用Proxy的GiveGift函数的时候,虽然you是有地址的,但是地址指向的内存已经被释放了,就会导致中断出错。

class Proxy :public IGiftOperation
{
public:
	Proxy() {};
	~Proxy() {};
	Proxy(Pursuit You)
	{
		you = &You;//不同点
	}
	void GiveGift()
	{
		you->GiveGift();//不同点
	}
private:
	Pursuit* you;//不同点
};

总结

这篇博客讲的代理模式原理比较简单,从代码层面来说就是用一个类A通过接口OP去调用另一个类B的操作,避免让类C直接和A接触。有一种间接的调用效果。


http://www.niftyadmin.cn/n/5664665.html

相关文章

Java 中的 FileWriter:用法详解与实战

FileWriter 是专门用于将字符写入文件的便捷类。它继承自 OutputStreamWriter&#xff0c;属于字符流类的一个部分&#xff0c;适合用于处理文本文件的写入操作。 1. FileWriter 概述 FileWriter 主要用于将字符数据写入到文件中。如果文件不存在&#xff0c;它会自动创建&…

四、JVM原理-4.1、JVM介绍

4.1、JVM介绍 4.1.1、如何理解Java虚拟机&#xff0c;它的结构是如何设计的&#xff1f; 答&#xff1a; Java虚拟机&#xff08;Java Virtual Machine&#xff0c;JVM&#xff09;是Java语言编写的程序在运行时的执行环境。它是Java的核心组成部分&#xff0c;负责解释和执行…

沉浸式体验Stability AI最新超强AI图片生成模型Ultra

2024年9月4日&#xff0c;亚马逊云科技在Amazon Bedrock上新了Stability AI最新的的三款文本图像生成模型&#xff1a;他们分别是Stable Image Ultra、Stable Diffusion 3 Large 和 Stable Image Core。全新的模型在处理多主题提示词、图像质量和图片排版上较上一代模型有显著提…

一个基于 laravel 和 amis 开发的后台框架, 友好的组件使用体验,可轻松实现复杂页面(附源码)

前言 随着互联网应用的发展&#xff0c;后台管理系统的复杂度不断增加&#xff0c;对于开发者而言&#xff0c;既要系统的功能完备&#xff0c;又要追求开发效率的提升。然而&#xff0c;传统的开发方式往往会导致大量的重复劳动&#xff0c;尤其是在构建复杂的管理页面时。有…

多目标优化算法(Multi-Objective Optimization Algorithms, MOOA)介绍

在现实世界中&#xff0c;许多问题都涉及到多个目标的权衡和优化。例如&#xff0c;在工程设计中&#xff0c;可能需要同时考虑成本、效率和可靠性&#xff1b;在资源管理中&#xff0c;可能需要平衡环境保护和经济效益。多目标优化算法&#xff08;Multi-Objective Optimizati…

Vue+nodejs+express旅游景区门票预订网站的设计与实现 8caai前后端分离

目录 技术栈具体实现截图系统设计思路技术可行性nodejs类核心代码部分展示可行性论证研究方法解决的思路Express框架介绍源码获取/联系我 技术栈 该系统将采用B/S结构模式&#xff0c;开发软件有很多种可以用&#xff0c;本次开发用到的软件是vscode&#xff0c;用到的数据库是…

大数据Flink(一百一十八):Flink SQL水印操作(Watermark)

文章目录 Flink SQL水印操作&#xff08;Watermark&#xff09; 一、为什么要有WaterMark 二、​​​​​​​​​​​​​​Watermark解决的问题 三、​​​​​​​​​​​​​​代码演示 Flink SQL水印操作&#xff08;Watermark&#xff09; 一、​​​​​​​为什么…

Java SE基础知识详解:源于技术书籍的深度解读

写在前面 ⭐️在无数次的复习巩固中&#xff0c;我逐渐意识到一个问题&#xff1a;面对同样的面试题目&#xff0c;不同的资料来源往往给出了五花八门的解释&#xff0c;这不仅增加了学习的难度&#xff0c;还容易导致概念上的混淆。特别是当这些信息来自不同博主的文章或是视…