虚拟代理模式-Virtual Proxy(Java实现)
虚拟代理模式-Virtual Proxy
虚拟代理模式(Virtual PRoxy)会推迟真正所需对象实例化时间. 在需要真正的对象工作之前, 如果代理对象能够处理, 那么暂时不需要真正对象来出手.
优点: 这种方法的优点是,在应用程序启动时,由于不需要创建和装载所有的对象,因此加速了应用程序的启动。
缺点: 因为不能保证特定的应用程序对象被创建,在访问这个对象的任何地方,都需要检测确认它不是空(null)。性能的降低上不仅仅是多了一句代码这么简单, ` if ` 这种跳转类语句的很有可能会阻塞CPU的指令流水, 虽然有分值预测技术, 但是分支预测也是有命中率的....
还是回过头讲讲本文的主题吧....
举个例子: 有一批人来找老板谈事情, 谈事情之前需要预约, 将这些预约添加到计划列表里. "将预约添加到计划列表里"这件事, 本身并不需要老板亲自现身, 老板不再的时候完全可以找一个助手来代做, 只有执行任务计划列表里的任务时, 老板才需现身处理(场景就是: 大家都是来找老板做事的, 并不是来找助手做事的, 助手只负责在老板不在的时候帮老板收集大家的需求, 最后收集完了, 他就把老板邀请过来, 老板来处理所有的事情).
Approvable接口
老板和助手都需要实现这个接口.
助手实现这个接口, 当调用助手的approve方法时, 助手就会去邀请老板过来, 让老板处理清单.
老板实现这个接口, 是因为这些清单就需要老板来处理(approve)
- public interface Approvable {
- void approve() ;
- }
Boss类
老板是有身价的, 来一趟不容易, 所以小事交给助手做(就比如: 收集访客们找老板有什么事情, 并统计出一个清单). 没必要一上来就把老板叫出来.
- import java.util.LinkedList;
- import java.util.List;
- public class Boss implements Approvable {
- List<String> orders;
- {
- System.out.println("\nBoss出现...\n");
- }
- public Boss() {
- this.orders = new LinkedList<>();
- }
- public Boss(List<String> orders) {
- if (orders != null) {
- this.orders = orders;
- } else {
- this.orders = new LinkedList<>();
- }
- }
- public void addOrder(String order) {
- this.orders.add(order);
- }
- @Override
- public void approve() {
- while(orders.size()>0){
- String order = orders.remove(0);
- System.out.println("Boss处理了任务<" + order + ">");
- }
- System.out.println();
- }
- }
Assistant类
Boss的代理类, 老板的助手.
- import java.util.LinkedList;
- import java.util.List;
- /**
- * Boss的代理
- * 负责收集orders列表, 处理清单之前的收集工作就不用老板现身了,
- * 老板可以晚一点出现
- */
- public class Assistant implements Approvable {
- List<String> orders;
- volatile Boss boss;
- public Assistant() {
- orders = new LinkedList<>();
- }
- public void addOrder(String order) {
- if (boss != null) {
- System.out.println("Boss亲自将<" + order + ">任务添加到列表");
- boss.addOrder(order);
- } else {
- System.out.println("助手将<" + order + ">任务添加到列表");
- this.orders.add(order);
- }
- }
- @Override
- public void approve() {
- inviteBoss();
- boss.approve();
- }
- private void inviteBoss() {
- if (boss == null) {
- synchronized (this) {
- if (boss == null) {
- boss = new Boss(orders);
- }
- }
- }
- }
- }
Main
用于运行, 场景模拟
- public class Main {
- public static void main(String[] args) {
- // 有很多人来找老板, 老板在忙, 助手先把所有事情安置好
- Assistant assistant = new Assistant();
- assistant.addOrder("我找Boss面试");
- assistant.addOrder("我找Boss借钱");
- assistant.addOrder("我找Boss聊天");
- // 收集好了, 助手的职责就完成了, 把Boss叫出来, 让Boss处理. 或者说approve这件事,助手是做不了的, 只能叫出Boss来做.
- assistant.approve();
- // Boss刚才就被邀请过来, 现在就在现场. 所以就不需要助手转告给Boss了. 大家告诉助手的事情, Boss也会听到
- assistant.addOrder("我找Boss吃饭");
- assistant.addOrder("我找Boss喝酒");
- assistant.approve();
- }
- }
虚拟代理模式-Virtual Proxy(Java实现)的更多相关文章
- 远程代理模式-Remote Proxy(Java实现)
远程代理模式-Remote Proxy 服务端通过rmi将对象注册到远程服务, 客户端使用时, 只需要通过rmi协议获取即可, 只要接口统一, 即可不需要知道内部具体实现, 直接调用使用. Compa ...
- 代理模式-JDK Proxy(Java实现)
代理模式-JDK Proxy 使用JDK支持的代理模式, 动态代理 场景如下: 本文例子代理了ArrayList, 在ArrayList每次操作时, 在操作之前和之后都进行一些额外的操作. Array ...
- 保护代理模式-Access Proxy(Java实现)
保护代理模式-Access Proxy 保护代理模式(Access Proxy), 也叫Protect Proxy. 这种代理用于对真实对象的功能做一些访问限制, 在代理层做身份验证. 通过了验证, ...
- 阿里架构师浅析Java设计模式之虚拟代理模式
虚拟代理模式(Virtual Proxy)是一种节省内存的技术,它建议创建那些占用大量内存或处理复杂的对象时,把创建这类对象推迟到使用它的时候.在特定的应用中,不同部分的功能由不同的对象组成,应用启动 ...
- JAVA设计模式(09):结构型-代理模式(Proxy)
代理模式是经常使用的结构型设计模式之中的一个,当无法直接訪问某个对象或訪问某个对象存在困难时能够通过一个代理对象来间接訪问,为了保证client使用的透明性,所訪问的真实对象与代理对象须要实现同样的接 ...
- JAVA设计模式(09):结构化-代理模式(Proxy)
一,定义: 代理模式(Proxy):为其它对象提供一种代理以控制对这个对象的訪问. 二.其类图: 三,分类一:静态代理 1,介绍:也就是须要我们为目标对象编写一个代理对象,在编译期就生成了这个代理对 ...
- java设计模式(10):代理模式(Proxy)
一,定义: 代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问. 二,其类图: 三,分类一:静态代理 1,介绍:也就是需要我们为目标对象编写一个代理对象,在编译期就生成了这个代理对 ...
- Java设计模式(10)代理模式(Proxy模式)
理解并使用设计模式,能够培养我们良好的面向对象编程习惯,同时在实际应用中,可以如鱼得水,享受游刃有余的乐趣. Proxy是比较有用途的一种模式,而且变种较多,应用场合覆盖从小结构到整个系统的大结构,P ...
- 【java项目实战】代理模式(Proxy Pattern),静态代理 VS 动态代理
这篇博文,我们主要以类图和代码的形式来对照学习一下静态代理和动态代理.重点解析各自的优缺点. 定义 代理模式(Proxy Pattern)是对象的结构型模式,代理模式给某一个对象提供了一个代理对象,并 ...
随机推荐
- deepin linux学习笔记
目录 deepin linux学习笔记 前言 linux常用命令 ls 显示文件夹内容 cd 切换当前目录 pwd 查看当前工作目录 mkdir 新建文件夹 rm 删除文件或文件夹 mv 移动文件 c ...
- Oracle下载与Oracle安装图解(Oracle19c,Oracle18c,Oracle12c,Oracle11g)
Oracle下载与Oracle安装图解(Oracle19c,Oracle18c,Oracle12c,Oracle11g) 1.Oracle下载(Oracle11g) oracle下载方法,请根据以下步 ...
- linux安装windows启动盘
安装gparted
- 分布式缓存Redis集群配置使用
Redis 简介 redis是一种开源的.基于内存的.可持久化的.高性能的Key-Value数据存储系统. redis能做什么? 持久化存储 高速缓存 消息中间件 ...
- YASnippet - emacs 的代码片段管理工具
添加 snippet M-x 然后输入 yas-new-snippet 回车 RET,会出现一个新的 buffer # -*- mode: snippet -*- # name: # key: # - ...
- springmvc源码分析——入门看springmvc的加载过程
本文将分析springmvc是如何在容器启动的时候将各个模块加载完成容器的创建的. 我知道在web.xml文件中我们是这样配置springmvc的: 可以看到,springmvc的核心控制器就是Dis ...
- Python学习案例之Web版语音合成播报
前言 语音合成技术能将用户输入的文字,转换成流畅自然的语音输出,并且可以支持语速.音调.音量设置,打破传统文字式人机交互的方式,让人机沟通更自然. 应用场景 将游戏场景中的公告.任务或派单信息通过语音 ...
- HashMap、Hashtable、ConcurrentHashMap的原理与区别
同步首发:http://www.yuanrengu.com/index.php/2017-01-17.html 如果你去面试,面试官不问你这个问题,你来找我^_^ 下面直接来干货,先说这三个Map的区 ...
- omit 配合antd from使用 hoistStatics
import omit from 'omit.js'; // 作用: 从已经存在的对象中过滤特定属性 const formProps = omit(this.props, [ 'prefixCls', ...
- Navicat 连接VMware中Ubuntu 下的mysql5.7遇到的坑
1.用Navicat连接虚拟机下的mysql出现问题: 2003- Can't connect MySQL Server on '192.168.*.*'(10038). 解决方案: 方法:直接授权( ...