定义

为其他对象提供一种代理,以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介的作用。(结构型)

如果不知道代理模式,可能大家对代理服务器都不叫熟悉。代替服务器代替请求者去发一起对另一个服务器的请求,他相当于请求的中间人。为什么要通过这个代理呢,那是因为客户端直接去访问服务器会被拒绝(防火墙屏蔽),而代理服务器则可以直接访问服务器。这里有两种应用场景,一种是国内的翻墙了(静态代理),另一种是hacker想掩盖自己的ip时,往往会通过多层代理服务器进行访问/或者不停的切换代理(动态代理,《who am i》电影里面男主就是通过代理去和另外一个haacker通信,而且所用的代理一直在变防止被追踪到)

模板

抽象角色(Subject)

通过接口或抽象类声明真实角色实现的业务方法。

代理角色(RealSubject)

实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作

真实角色(Proxy)

实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用

实例

a) 静态代理



Main中去调用ProxyPrinter中的print方法而不需要关心被代理类(Printer),由于代码比较简单,这里就不具体展开。

b) 动态代理

这里列举了一个可以将任何方法的执行放在指定线程(提前创建好的UI线程和后台线程)的动态代理实现,具体如下:

假如一个有一个写文件的操作类如下:

public class FileWriter {

    private void writeBytesToFile(String fileName, Byte[] bytes) {
// 将二进制文件写入到 文件中
}
}

做过前端开发的应该都知道写文件是一个耗时操作,不能在主线程中执行,那我们现在怎么办?

FileWriter fileWriter = new FileWriter();
FileWriter proxyWriter = ObjectThreadProxy.back(fileWriter, FileWriter.class);
proxyWriter.writeBytesToFile("TestFile.txt", xxxx);

上述代码通过前面讲的ObjectThreadProxy工具类就可以将被代理的对象转换成proxyWriter,接下来调用proxyWriter的任何方法都会执行在子线程中。这是如何做到的,具体看一下back方法及ThreadInvocationHandler就知道了:

// back 方法中创建代理类
ThreadInvocationHandler handler = new ThreadInvocationHandler(realObj, syncMode);
Object proxyObj = Proxy.newProxyInstance(class.getClassLoader(), new Class[]{class}, handler);
return proxyObj; // ThreadInvocationHandler 中invoke方法关键代码如下:
public Object invoke(Object proxy, final Method method, final Object[] args) {
switch(mode) {
case BACK:
// 在子线程执行方法
method.invoke(readObject, args);
break;
case MAIN:
// 在主线程中执行
break;
}

优点

1.代理模式能将代理对象与真实对象被调用的目标对象分离,一定程度上降低了系统的耦合度,扩展性好。

2.保护目标对象。

3.增强目标对象。

缺点

  1. 创建多个类,增加代码阅读复杂性(所有设计模式通病)
  2. clone方法只是浅拷贝,除五种基础类型之外类型都只是简单的指向引用,不会重新创建成员变量,如需实现需要自定义clone方法。
  3. 通过clone方法不会调用类的构造函数,部分场景(在构造函数中做一些初始化操作的)需要做额外的处理

适用场景

1.保护目标对象

2.增强目标对象

与装饰模式的区别

对对象的作用

装饰者:动态的新增或组合对象的行为,在不改变接口的前提下,动态扩展对象的功能

代理模式:为其他对象提供一种代理以控制对这个对象的访问,在不改变接口的前提下,控制对象的访问

如何使用该对象

装饰者:通常将原始对象作为参数传递给Decorator的构造函数。

代理模式:代理类中创建一个真实对象的实例

注: 其实代理模式也可以作为参数传递,这里是网上很多地方的写法,自己并不赞同。

模式的核心

装饰者:强调的是增强自身,在被装饰之后你能够在被增强的类上使用增强后的功能。增强后你还是你,只不过能力更强了而已

代理模式:强调要让别人去做一些本身和你业务没有太多关系的职责(记录日志,设置缓存,远程代理负责网络通信的一些细节),代理模式是为了实现对对象的控制,因为被代理的对象往往难以直接获得或者其内部不想暴露出来

其它实例:

待补充

设计模式——代理模式(Proxy)的更多相关文章

  1. 设计模式——代理模式(Proxy Pattern)

    代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. UML图: 模型设计: Subject类: package com.cnblog.clarck; /** * Subject 类 ...

  2. 设计模式 - 代理模式(proxy pattern) 未使用代理模式 具体解释

    代理模式(proxy pattern) 未使用代理模式 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 部分代码參考: http://blog.csdn. ...

  3. 设计模式--代理模式Proxy(结构型)

    一.代理模式 为其他对象提供一种代理以控制对这个对象的访问. 代理模式分为四种: 远程代理:为了一个对象在不同的地址空间提供局部代表.这样可以隐藏一个对象存在于不同地址空间的事实. 虚拟代理:根据需要 ...

  4. C#设计模式——代理模式(Proxy Pattern)

    一.概述在软件开发中,有些对象由于创建成本高.访问时需要与其它进程交互等原因,直接访问会造成系统速度慢.复杂度增大等问题.这时可以使用代理模式,给系统增加一层间接层,通过间接层访问对象,从而达到隐藏系 ...

  5. 设计模式-代理模式(Proxy)

    应用场景: 领导都有秘书,一般会代理领导的部分职能角色,处理签字.报销.开会等任务.很多新人可能都只知道秘书的存在,毕竟每天与其打交道,不知道领导的存在.但是领导的的确确是真实存在的. 场景说明: 代 ...

  6. 大话设计模式--代理模式 proxy

    1. 代理模式: 为其他对象提供一种代理以控制这个对象的访问. 代理模式使用场合: a. 远程代理, 为一个对象在不同的地址空间提供局部代理,隐藏一个对象存在于不同地址空间的事实.如.net中WebS ...

  7. 23种设计模式--代理模式-Proxy

    一.代理模式的介绍       代理模式我们脑袋里出现第一个词语就是代购,其实就是这样通过一个中间层这个中间成是属于什么都干什么都买得,俗称"百晓生",在平时得开发中我们经常会听到 ...

  8. 设计模式 -- 代理模式 (Proxy Pattern)

    定义: 为其他对象提供一种代理以控制对这个对象的访问: 角色: 1,抽象主题类,(接口或者抽象类),抽象真实主题和代理的共有方法(如下Subject类): 2,具体实现的主题类,继承或者实现抽象主题类 ...

  9. 深入浅出设计模式——代理模式(Proxy Pattern)

    模式动机在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用.代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到 ...

  10. 【转】设计模式(十一)代理模式Proxy(结构型)

    设计模式(十一)代理模式Proxy(结构型) 1.概述 因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗 ( if和else就是不同的两条逻辑路径) ...

随机推荐

  1. Dubbo配置完全外部化实践,使用动态配置中心的注意事项

    问题描述 近期开发项目,将Dubbo的配置全部外部化到动态配置中心.这里配置中心我使用的是Apollo. @Configuration public class DubboConfig { @Bean ...

  2. MyEclipse 2013配置JDBC连接mySQL||Tomcat 7.0 8.0 配置 JDBC |配置mysql-connector-java-5.1.16

    MyEclipse->Preferences->MyEclipse->Severs->Intergated Sandbox->Myeclipse Tomcat 7(或者T ...

  3. Java基础(40)String、StringBuilder和StringBuffer的区别(TODO)

    一.String String实现了Serializable接口.Comparable<String>接口和CharSequence接口,并且使用final char value[]不可变 ...

  4. jwt token

    1 ,session 认证机制: ,用户登录,传递用户名和密码给客户端 ,服务器进行用户名和密码的校验,如果校验成功,将用户保存到session ,将sessionid通过cookie返回给客服端,客 ...

  5. Coremail接口存配置读取漏洞POC

    Coremail产品诞生于1999年,经过二十多年发展,如今从亿万级别的运营系统,到几万人的大型企业,都有了Coremail的客户. 截止2019年,Coremail邮件系统产品在国内已拥有10亿终端 ...

  6. 运用wxs制作微信小程序左滑功能和跳转,性能更优越

    锲子 微信小程序自定义左滑功能加上跳转,换成以往,左滑功能的逻辑一般是在js中实现,但在拖动方面,性能并不是那么的流畅.如今,官方新扩展了一套脚本语言wxs,在IOS设备上运行,性能会比JS快2~20 ...

  7. php判断是不是https的方法

    php判断是不是https的方法<pre> public function is_https() { if (!empty($_SERVER['HTTPS']) && st ...

  8. 多线程之美1一volatile

    目录 一.java内存模型 1.1.抽象结构图 1.2.概念介绍 二.volatile详解 2.1.概念 2.2.保证内存可见性 2.3.不保证原子性 2.4.有序性 一.java内存模型 1.1.抽 ...

  9. jdk 错误1316 指定账户已存在 与 jdk1.7安装和配置环境变量 与 jdk1.8与1.7版本的切换使用

    问题:         安装JDK,提示错误信息:,指定的账号已存在. 原因:         安装JDK,相当于安装了一个软件,要使用系统的软件卸载功能卸载,不能只删除安装目录文件夹下的文件,如果只 ...

  10. Spring注解@Configuration是如何被处理的?

    从SpringApplication开始 一般情况下启动SpringBoot都是新建一个类包含main方法,然后使用SpringApplication.run来启动程序: @SpringBootApp ...