作为一个初级开发者,可能不会接触到代理模式,但是在很多框架的使用中都不知不觉使用了代理模式,比如servlet的过滤器链,spring的AOP,以及spring mvc的拦截器等。所以了解代理模式对于个人的成长是不可避免的。

  在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。

原文和作者一起讨论:http://www.cnblogs.com/intsmaze/p/6013461.html

    通过引入一个新的对象来实现对真实对象的操作或者将新的对象作为真实对象的一个替身,这种实现机制即为代理模式,通过引入代理对象来间接访问一个对象,这就是代理模式的模式动机。 
 
    代理模式(Proxy Pattern) :给某一个对象提供一个代理,并由代理对象控制对原对象的引用。代理模式的英文叫做Proxy或Surrogate,它是一种对象结构型模式。
    代理模式示意结构图比较简单,一般可以简化为如下图所示,但是在现实中要复杂很多。
 
如下的场景来理解为什么采用聚合而不是继承调用:
public interface Moveable {
void move();
void stop();
}
public class Tank implements Moveable {
public void move() {
System.out.println("Tank Move");
try {
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void stop() {
System.out.println("Tank stop");
}
}
现在我们要增加一个功能,记录move方法的执行时间,不能修改源码。

方式1:采用继承

public class Tank1 extends Tank {
public void move() {
System.out.println("time start");
super.move();
System.out.println("time end");
}
}

再增加一个功能,记录move的执行前后的日志信息,不能修改源码。

public class Tank2 extends Tank {
public void move() {
System.out.println("log start");
super.move();
System.out.println("log end");
}
}
但是要是想先记录日志在记录时间,那么就要再创建一个类继承Tank1类。
要先记录时间再记录日志,就要再创建一个类继承Tank2类。
代理模式不采用继承模式,因为扩展性很差的。
 

方式二:采用聚合模式

public class TimeProxy implements Moveable {
Moveable m;
public TimeProxy(Moveable m) {
super();
this.m = m;
}
public void move() {
System.out.println("time start");
m.move();
System.out.println("time end");
}
} public class LogProxy implements Moveable {
Moveable m;
public LogProxy(Moveable m) {
super();
this.m = m;
}
public void move() {
System.out.println("log start");
m.move();
System.out.println("log end");
}
}

想添加日志功能

  public static void main(String[] args) throws Exception {
Moveable t = new Tank();
Moveable m=new LogProxy(t);
m.move();
}

想先日志再时间,直接在调用处进行组合,不需要创建新的类

public static void main(String[] args) throws Exception {
Moveable t = new Tank();
Moveable m=new LogProxy(t);
Moveable s=new TimeProxy(m);
s.move();
}

如果要对Moveable接口中所有的方法加时间计算

public class TimeProxy implements Moveable {
Moveable m;
public TimeProxy(Moveable m) {
super();
this.m = m;
}
public void move() {
this.before();
m.move();
this.after();
}
@Override
public void stop() {
this.before();
m.stop();
this.after();
}
public void before()
{
System.out.println("time start");
}
public void after()
{
System.out.println("time end");
}
}

代理模式的优点

代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。
远程代理使得客户端可以访问在远程机器上的对象,远程机器可能具有更好的计算性能与处理速度,可以快速响应并处理客户端请求。
虚拟代理通过使用一个小对象来代表一个大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。
保护代理可以控制对真实对象的使用权限。

代理模式的缺点

由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

java代理模式之静态代理的更多相关文章

  1. java 代理模式(静态代理、动态代理、Cglib代理) 转载

    Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...

  2. Java三种代理模式:静态代理、动态代理和cglib代理

    一.代理模式介绍 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能. 简言之,代理模式就是 ...

  3. Spring框架_代理模式(静态代理,动态代理,cglib代理)

    共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下:                 ...

  4. 【Java】代理模式,静态代理和动态代理(基于JDK或CGLib)

    当我们需要在一个方法之前或之后添加一段逻辑时,自然会想到使用代理类.代理类帮我们代理了实际类的调用,然后可以在实际调用之前和之后添加一些逻辑,从而不浸入实际类. 拓展:由于代理类能在实际类调用之前和之 ...

  5. java 编程基础 Class对象 反射:代理模式和静态代理

    生活中的代理 类(对象)代理模式 代理模式是面向对象编程中比较常见的设计模式. 1. 用户只关心接口功能,而不在乎谁提供了功能.上图中接口是 Subject 2. 接口真正实现者是上图的 RealSu ...

  6. Java的三种代理模式:静态代理/JDK动态代理/Cglib动态代理

    1.静态代理:需要定义接口或者父类,目标对象与代理对象均实现同一接口或继承同一父类. 2.JDK动态代理:需要目标对象实现一个接口,通过动态反射的机制,生成代理对象,实现同一个接口 3.Cglib动态 ...

  7. 代理模式之静态代理,JDK动态代理和cglib动态代理

    代理模式,顾名思义,就是通过代理去完成某些功能.比如,你需要购买火车票,不想跑那么远到火车站售票窗口买,可以去附近的火车票代售点买,或者到携程等第三方网站买.这个时候,我们就把火车站叫做目标对象或者委 ...

  8. 结构型模式 -- 代理模式(静态代理&动态代理)

    静态代理: 真实角色和代理角色实现相同的接口,代理角色拥有真实角色的引用.代理角色去执行方法,对于某些"真正"需要真实角色自己执行的方法时,在代理角色内部就调用真实角色的方法,其他 ...

  9. Java设计模式之代理模式(静态代理和JDK、CGLib动态代理)以及应用场景

    我做了个例子 ,需要可以下载源码:代理模式 1.前言: Spring 的AOP 面向切面编程,是通过动态代理实现的, 由两部分组成:(a) 如果有接口的话 通过 JDK 接口级别的代理 (b) 如果没 ...

随机推荐

  1. BPM任务管理解决方案分享

    一.方案概述任务是企业管理者很多意志的直接体现,对于非常规性事务较多的企业,经常存在各类公司下达的各种任务跟进难.监控难等问题,任务不是完成效果不理解,就是时间超期,甚至很多公司管理层下达的任务都不了 ...

  2. BPM配置故事之案例14-数据字典与数据联动

    小明遇到了点麻烦,他昨天又收到了行政主管发来的邮件,要求把出差申请单改由H3 BPM进行,表单如下 行政主管的出差申请表 小明对表单进行了调整,设计出了一份适合在系统中使用的表单,但在"出差 ...

  3. 自定义控件之 圆形 / 圆角 ImageView

    一.问题在哪里? 问题来源于app开发中一个很常见的场景——用户头像要展示成圆的:       二.怎么搞? 机智的我,第一想法就是,切一张中间圆形透明.四周与底色相同.尺寸与头像相同的蒙板图片,盖在 ...

  4. Maven(一)linux下安装

    1.检查是否安装JDK,并且设置了环境变量(JAVA_HOME): echo $JAVA_HOME java -version 运行结果: 显示jdk的安装路径,和java的版本,如: #jdk路径 ...

  5. linux系统oracle-ora12505问题解决方案一

    说明:(1)Linux版本 Linux version 2.6.32.12-0.7-default (geeko@buildhost) (gcc version 4.3.4 [gcc-4_3-bran ...

  6. NOIP2016纪录[那些我所追求的]

    人生第一场正式OI [序] 2016-12-04 见底部 [Day -1] 2016-11-17 期中考试无心插柳柳成荫,考了全市第2班里第1(还不是因为只复习了不到两天考试),马上请了一个周的假准备 ...

  7. BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9812  Solved: 3978[Submit][St ...

  8. 自定义可视化调试工具(Microsoft.VisualStudio.DebuggerVisualizers)

    前言: 最近飞机失联的太多,明天要飞北京处理服务器双机热备的问题,航空保险已买,单号是:TF10122913. 至于我的银行卡密码,在我枕头下面的字条里,要是我之后没再更新文章,请通知我家人,哈哈哈哈 ...

  9. 【腾讯Bugly干货分享】Android动态布局入门及NinePatchChunk解密

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57c7ff5d53bbcffd68c64411 作者:黄进——QQ音乐团队 摆脱 ...

  10. 弄了一个支持SSL的TCP客户端

    近日需要做一些TCP的收发的调试,到网上去找TCP调试工具,找了好几款,发现不是功能不全就是不支持HEX,更重要的SSL也不支持,于是动手写了一款,叫TCPRunner,有以下特性: 使用异步IO方式 ...