设计模式——代理模式(Proxy)
定义
为其他对象提供一种代理,以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介的作用。(结构型)
如果不知道代理模式,可能大家对代理服务器都不叫熟悉。代替服务器代替请求者去发一起对另一个服务器的请求,他相当于请求的中间人。为什么要通过这个代理呢,那是因为客户端直接去访问服务器会被拒绝(防火墙屏蔽),而代理服务器则可以直接访问服务器。这里有两种应用场景,一种是国内的翻墙了(静态代理),另一种是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.增强目标对象。
缺点
- 创建多个类,增加代码阅读复杂性(所有设计模式通病)
- clone方法只是浅拷贝,除五种基础类型之外类型都只是简单的指向引用,不会重新创建成员变量,如需实现需要自定义clone方法。
- 通过clone方法不会调用类的构造函数,部分场景(在构造函数中做一些初始化操作的)需要做额外的处理
适用场景
1.保护目标对象
2.增强目标对象
与装饰模式的区别
对对象的作用
装饰者:动态的新增或组合对象的行为,在不改变接口的前提下,动态扩展对象的功能
代理模式:为其他对象提供一种代理以控制对这个对象的访问,在不改变接口的前提下,控制对象的访问
如何使用该对象
装饰者:通常将原始对象作为参数传递给Decorator的构造函数。
代理模式:代理类中创建一个真实对象的实例
注: 其实代理模式也可以作为参数传递,这里是网上很多地方的写法,自己并不赞同。
模式的核心
装饰者:强调的是增强自身,在被装饰之后你能够在被增强的类上使用增强后的功能。增强后你还是你,只不过能力更强了而已
代理模式:强调要让别人去做一些本身和你业务没有太多关系的职责(记录日志,设置缓存,远程代理负责网络通信的一些细节),代理模式是为了实现对对象的控制,因为被代理的对象往往难以直接获得或者其内部不想暴露出来
其它实例:
待补充
设计模式——代理模式(Proxy)的更多相关文章
- 设计模式——代理模式(Proxy Pattern)
代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. UML图: 模型设计: Subject类: package com.cnblog.clarck; /** * Subject 类 ...
- 设计模式 - 代理模式(proxy pattern) 未使用代理模式 具体解释
代理模式(proxy pattern) 未使用代理模式 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 部分代码參考: http://blog.csdn. ...
- 设计模式--代理模式Proxy(结构型)
一.代理模式 为其他对象提供一种代理以控制对这个对象的访问. 代理模式分为四种: 远程代理:为了一个对象在不同的地址空间提供局部代表.这样可以隐藏一个对象存在于不同地址空间的事实. 虚拟代理:根据需要 ...
- C#设计模式——代理模式(Proxy Pattern)
一.概述在软件开发中,有些对象由于创建成本高.访问时需要与其它进程交互等原因,直接访问会造成系统速度慢.复杂度增大等问题.这时可以使用代理模式,给系统增加一层间接层,通过间接层访问对象,从而达到隐藏系 ...
- 设计模式-代理模式(Proxy)
应用场景: 领导都有秘书,一般会代理领导的部分职能角色,处理签字.报销.开会等任务.很多新人可能都只知道秘书的存在,毕竟每天与其打交道,不知道领导的存在.但是领导的的确确是真实存在的. 场景说明: 代 ...
- 大话设计模式--代理模式 proxy
1. 代理模式: 为其他对象提供一种代理以控制这个对象的访问. 代理模式使用场合: a. 远程代理, 为一个对象在不同的地址空间提供局部代理,隐藏一个对象存在于不同地址空间的事实.如.net中WebS ...
- 23种设计模式--代理模式-Proxy
一.代理模式的介绍 代理模式我们脑袋里出现第一个词语就是代购,其实就是这样通过一个中间层这个中间成是属于什么都干什么都买得,俗称"百晓生",在平时得开发中我们经常会听到 ...
- 设计模式 -- 代理模式 (Proxy Pattern)
定义: 为其他对象提供一种代理以控制对这个对象的访问: 角色: 1,抽象主题类,(接口或者抽象类),抽象真实主题和代理的共有方法(如下Subject类): 2,具体实现的主题类,继承或者实现抽象主题类 ...
- 深入浅出设计模式——代理模式(Proxy Pattern)
模式动机在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用.代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到 ...
- 【转】设计模式(十一)代理模式Proxy(结构型)
设计模式(十一)代理模式Proxy(结构型) 1.概述 因为某个对象消耗太多资源,而且你的代码并不是每个逻辑路径都需要此对象, 你曾有过延迟创建对象的想法吗 ( if和else就是不同的两条逻辑路径) ...
随机推荐
- python之ORM(对象关系映射)
实现了数据模型与数据库的解耦,通过简单的配置就可以轻松更换数据库,而不需要更改代码.orm操作本质上会根据对接的数据库引擎,翻译成对应的sql语句.所有使用Django开发的项目无需关心程序底层使用的 ...
- django-URL之从URL中获取关键字(七)
主要用于查询操作. 主要目录 book/views.py from django.http import HttpResponse from django.shortcuts import rende ...
- Alpha阶段--第七周Scrum Meeting
任务内容 本次会议为第六周的Scrum Meeting会议 召开时间为周日下午5点,在潮音餐厅召开,召开时间约为30分钟,对已经完成项目的总结和对今后项目设计的展望 队员 任务 张孟宇 “我的”界面代 ...
- mysql全局变量和局部变量
全局变量和局部变量 在服务器启动时,会将每个全局变量初始化为其默认值(可以通过命令行或选项文件中指定的选项更改这些默认值).然后服务器还为每个连接的客户端维护一组会话变量,客户端的会话变量在连接时使用 ...
- Ubuntu16.04下升级Python到3.6
转: 这里 有一篇帖子是说从源代码开始安装,这种方式原来尝试过,需要删除系统默认的软链命令,感觉比较粗暴,现在在想有没有更好的方式呢? 找到一个帖子:http://ubuntuhandbook.org ...
- 一:XMind
- MySQL计划任务(事件调度器)
原文:http://www.cnblogs.com/c840136/articles/2388512.html 备忘; MySQL5.1.x版本中引入了一项新特性EVENT,顾名思义就是事件.定时任务 ...
- CentOS生产环境无网络安装percona-xtrabackup2.4【RPM安装教程】
Percona XtraBackup 8.0不支持对在MySQL 8.0之前的版本,Percona Server for MySQL或 Percona XtraDB Cluster中创建的数据库进行备 ...
- RESTful基本概念
文章目录 01 前言 02 RESTful的来源 03 RESTful6大原则 1. C-S架构 2. 无状态 3.统一的接口 4.一致的数据格式 4.系统分层 5.可缓存 6.按需编码.可定制代码( ...
- 八、springboot 简单优雅的通过docker-compose 构建
前言 这个项目有一段时间没有更新了,不过我可没有偷懒哟,是偷偷准备了一个大招,现在是时候展示啦哈哈. 我们今天要做的,就是将我们的项目通过docker-compose 构建成镜像运行.为什么要这样做呢 ...