前言大家好,我是秃头JAVA人 。你们是否在编程中经常遇见这样一个问题,对于访问某个对象,我们希望给它的方法前加入一个标记,比如对象的方法开始执行、结束等等(比如日志记录) 。怎么办呢,这个时候只要我们编写一个复制的类,然后把这个对象传给这个类,再对这个类进行操作,不就可以了吗 。这就是代理模式,复制的类就是代理对象,通过代理对象与我们进行打交道就可以对它原来的对象进行改造 。对于有些时候现有的对象不能满足我们的需求的时候,如何对它进行扩展,对方法进行改造,使其适用于我们所面临的问题,这就是代理模式的思维出发点 。
目录一:代理模式的介绍
二:实现静态代理
三:代理的进阶:实现动态代理
四:总结
接下来按照目录,我们来依次讲解本篇博客:
一:代理模式的介绍
1.1:目标
为其他对象提供一种代理以控制对这个对象的访问
解释:在实际编程中我们会产生一个代理对象,然后去引用被代理对象,对被代理对象进行控制与访问,实现客户端对原代理对象的访问,详情见下面的代码示例 。
1.2:适用性
在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy 模式 。下面是一 些可以使用Proxy 模式常见情况:
1.2.1:远程代理(Remote Proxy )为一个对象在不同的地址空间提供局部代表 。NEXTSTEP[Add94] 使用N X P r o x y 类实现了这一目的 。
1.2.2:虚代理(Virtual Proxy )根据需要创建开销很大的对象 。在动机一节描述的I m a g e P r o x y 就是这样一种代理的例子 。
1.2.3: 保护代理(Protection Proxy )控制对原始对象的访问 。保护代理用于对象应该有不同 的访问权限的时候
1.2.4: 智能指引(Smart Reference )取代了简单的指针,它在访问对象时执行一些附加操作 。
1.3:结构
文章插图
二:实现静态代理
2.1:代码场景
假如我们现在由以下的场景:文件编辑器要对一个图像文件进行操作,遵循以下顺序:加载,绘制,获取长度和宽度,存储四个步骤,但是有个问题,需要被加载的图片非常大,每次加载的时候都要耗费很多时间 。并且我们希望对图片的操作可以记录出来操作的步骤,比如第一步、第二步这样便于我们去理解 。为了解决这个问题,我们可以先考虑解决第一个问题就是利用代理模式去新建一个代理对象,然后在代理对象里去实现一个缓存,这样下次我们直接可以去缓存里面取对象,而不用去新建,这样就省去了新建对象消耗的资源 。另一方面,我们可以考虑去引用原来的方法,再给这方法基础上添加我们所要做的记录 。接下里我们用java代码来实现这个场景:
2.2:代码示范
【深度解析Java静态代理与动态代理模式的实现】2.2.1:首先新建一个接口,命名为Graphic,其中主要规范了我们进行操作的步骤
public interface Graphic {void load();//加载void Draw();//绘制Extent GetExtent();//获取长度和宽度void Store();//存储}
2.2.2:然后去新建一个Image类,用于实现接口,对操作进行具体控制,注意为了其中的Extent是对宽度和长度的封装(省略get和set方法)public class Image implements Graphic{public Image() {try {Thread.sleep(2000); //模拟创建需要花费很久的时间System.out.println("正在创建对象");} catch (Exception e) {e.printStackTrace();}}@Overridepublic void load() {System.out.println("进行加载..");}@Overridepublic void Draw() {System.out.println("进行绘画..");}@Overridepublic Extent GetExtent() {Extent extent = new Extent("100","200");System.out.println("获取图片的属性是:"+extent.toString());return extent;}@Overridepublic void Store() {System.out.println("图片进行存储在硬盘里..");}}
public class Extent {private String width;private String length;public Extent(String width, String length) {super();this.width = width;this.length = length;}//getter And setter方法}
2.2.3:接下来就是很关键的一步了,新建我们的代理类,我们新建一个类叫做ImageProxy,然后实现缓存与记录的效果:import java.util.HashMap;import java.util.Map;public class ImageProxyimplements Graphic{private Image image;private Map<String , Image> cache= new HashMap<String, Image>();//缓存public ImageProxy() {init();}public void init(){ //只需要初始化一次if (image==null) {image= new Image();cache.put("image", image);//放入缓存}else{image=cache.get("image");}@Overridepublic void load() {System.out.println("---第一步开始---");image.load();System.out.println("---第一步结束---");}@Overridepublic void Draw() {System.out.println("---第二步开始---");image.Draw();System.out.println("---第二步结束---");}@Overridepublic Extent GetExtent() {System.out.println("---第三步开始---");Extent extent = image.GetExtent();System.out.println("---第三步结束--");return extent;}@Overridepublic void Store() {System.out.println("---第四步开始---");image.Store();System.out.println("---第四步结束--");}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 解析服务型智能机器人的学习方法论
- 摩托罗拉|全球首发2亿像素!陈劲晒moto X30 Pro真机样张:解析力超强
- must+have done用法解析 done是什么意思
- 深度体验拼多多旗舰机 VJVJ vj是什么
- 简单百搭帽子编织方法步骤解析 帽子织法
- 改善Java代码的八个建议
- JavaScript实战3D建模软件开发
- 天文航天|23吨全球第一!中国“问天”舱深度揭秘:这5点无敌
- While用法解析及其和when 与as区别 while是什么意思
- CNN通俗解析 cnn是什么