一、代理模式是什么?

  代理模式属于GOF23设计模式中结构型中的设计模式,通过代理对象来屏蔽(部分或者屏蔽)对真实对象的直接访问,下图为UML图:

  在代理模式中组件包括:抽象角色接口、代理角色类、真实角色类。

  抽象角色:声明真实对象和代理对象的共同接口。
  代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
  真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

  实际上代理又分为动态代理和静态代理,在实际开发中使用比较多的是动态代理。在主题三种将分别对动态代理和静态代理给出具体的示例。

  所谓的静态代理就是由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。而动态代理就是在程序运行时运用反射机制动态创建而成。

二、为什么用代理模式

1、远程代理,为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在于不同地址空间的事实。

2、虚拟代理,根据需要创建开销很大的对象。通过它来存放实例化需要很长时间的真实对象。例如,网页中在图片出来以前现出来文字。

3、安全代理,用来控制真实对象访问时的权限。

4、智能代理,是指当调用真实的对象时,代理处理另外一些事。

注:代理模式是AOP编程的核心实现之一。

三、怎么用代理模式

3.1:静态代理示例

源码已经上传GitHub:https://github.com/wanyouxian/DesignPatterns,工程名为:StaticProxy

定义抽象角色接口:

 package com.rocky.staticproxy;

 public interface IRenting
{
/*
* 看房子
*/
public void watchingHouse(); /**
* 签合同
*/
public void signContract(); /**
* 取钥匙
*/
public void takeKey();
}

定义代理对象类,实现抽象角色接口,该类持有真实对象引用

 package com.rocky.staticproxy;

 public class HouseProxy implements IRenting
{ private IRenting landLord = null; public HouseProxy(IRenting landLord)
{
this.landLord = landLord;
} @Override
public void watchingHouse()
{
System.out.println("HouseProxy.watchingHouse");
} @Override
public void signContract()
{
landLord.signContract();
} @Override
public void takeKey()
{
System.out.println("HouseProxy.takeKey");
}
}

定义真实对象类,实现抽象接口

 package com.rocky.staticproxy;

 public class LandLord implements IRenting
{ @Override
public void watchingHouse()
{
System.out.println("LandLord.watchingHouse");
} @Override
public void signContract()
{
System.out.println("LandLord.signContract");
} @Override
public void takeKey()
{
System.out.println("LandLord.takeKey");
}
}

编写测试类

 package com.rocky.testdriver;

 import com.rocky.staticproxy.HouseProxy;
import com.rocky.staticproxy.IRenting;
import com.rocky.staticproxy.LandLord; public class TestDriver
{ public static void main(String[] args)
{
IRenting landLord = new LandLord();
IRenting houseProxy = new HouseProxy(landLord); houseProxy.watchingHouse(); houseProxy.signContract(); houseProxy.takeKey();
} }

3.2:动态代理示例

  动态代理有多种实现方式,并且在开发中实际使用的比较多,特别是AOP编程的核心实现机制。AOP动态代理主要是通过jdk动态代理和cglib动态代理实现,jdk动态代理是由Java内部的反射机制来实现的,cglib动态代理底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。下面示例中通过JDK实现动态代理作为演示demo,源码已经上传GitHub:https://github.com/wanyouxian/DesignPatterns,工程名为:DynamicProxy

定义抽象角色:

 package com.rocky.dynamicproxy;

 public interface IRenting
{
/*
* 看房子
*/
public void watchingHouse(); /**
* 签合同
*/
public void signContract(); /**
* 取钥匙
*/
public void takeKey();
}

定义真实对象类:

 package com.rocky.dynamicproxy;

 public class LandLord implements IRenting
{ @Override
public void watchingHouse()
{
System.out.println("房东把房子挂到中介");
} @Override
public void signContract()
{
System.out.println("房东自己签租房合同"); } @Override
public void takeKey()
{
System.out.println("中介把房子钥匙给房客"); } }

定义代理对象处理器:

 package com.rocky.dynamicproxy;

 public class LandLord implements IRenting
{ @Override
public void watchingHouse()
{
System.out.println("房东把房子挂到中介");
} @Override
public void signContract()
{
System.out.println("房东自己签租房合同"); } @Override
public void takeKey()
{
System.out.println("中介把房子钥匙给房客"); } }

编写测试类:

 package com.rocky.testdriver;

 import java.lang.reflect.Proxy;

 import com.rocky.dynamicproxy.IRenting;
import com.rocky.dynamicproxy.LandLord;
import com.rocky.dynamicproxy.RentInvocationHandler; public class TestDriver
{ public static void main(String[] args)
{
IRenting landLord = new LandLord();
RentInvocationHandler handler = new RentInvocationHandler(landLord); IRenting proxy = (IRenting) Proxy.newProxyInstance(landLord.getClass().getClassLoader(),
landLord.getClass().getInterfaces(), handler); proxy.watchingHouse();
proxy.signContract();
proxy.takeKey();
} }

结构型--代理模式(Proxy)的更多相关文章

  1. JAVA设计模式(09):结构型-代理模式(Proxy)

    代理模式是经常使用的结构型设计模式之中的一个,当无法直接訪问某个对象或訪问某个对象存在困难时能够通过一个代理对象来间接訪问,为了保证client使用的透明性,所訪问的真实对象与代理对象须要实现同样的接 ...

  2. 结构型---代理模式(Proxy Pattern)

    代理模式的详细介绍 代理模式按照使用目的可以分为以下几种: 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象.这个不同的地址空间可以是本电脑中,也可以在另一台电脑中.最典型 ...

  3. 代理模式/proxy模式/结构型模式

    代理模式proxy 定义 为其他对象提供一种代理,并以控制对这个对象的访问.最简单的理解,买东西都是要去商店的,不会去工厂. java实现三要素 proxy(代理)+subject(接口)+realS ...

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

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

  5. 代理模式 PROXY Surrogate 结构型 设计模式(十四)

    代理模式 PROXY 别名Surrogate 意图 为其他的对象提供一种代理以控制对这个对象的访问. 代理模式含义比较清晰,就是中间人,中介公司,经纪人... 在计算机程序中,代理就表示一个客户端不想 ...

  6. 设计模式系列之代理模式(Proxy Pattern)——对象的间接访问

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  7. 代理模式(Proxy pattern)

    代理模式(proxy pattern):作用:为其他对象提供一种代理,以控制对这个对象的访问.代理对象在客户端对象和目标对象之间起中介的作用. 代理模式涉及到的角色: 抽象角色:声明真实对象和代理对象 ...

  8. 13.代理模式(Proxy Pattern)

    using System; namespace Test { //抽象角色:声明真实对象和代理对象的共同接口. //代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象, //同时代理 ...

  9. 大熊君说说JS与设计模式之------代理模式Proxy

    一,总体概要 1,笔者浅谈 当我们浏览网页时,网页中的图片有时不会立即展示出来,这就是通过虚拟代理来替代了真实的图片,而代理存储了真实图片的路径和尺寸,这就是代理方式的一种. 代理模式是比较有用途的一 ...

随机推荐

  1. ArchLinux下Ecplise软件报错

    如果你的Java出现了一下问题:An error has occurred. See error log for more details.java.lang.NullPointerException ...

  2. TCP/IP协议之分层

     应用层和运输层只在端系统(End System)中实现, 底层协议在中间系统(Intermediate System)实现 ICMP和IGMP属于网络层的附属协议.虽然其内容是IP数据报的载荷(P ...

  3. 在iOS7中修改键盘Return键的类型

    今天将之前运行在iOS7之前的一段代码拿出来,在iOS7的机器上运行,发现键盘上的ReturnKeyType不能被修改了. 经过几番查找资料,了解到iOS7中UISearchBar的结构发生了变化,将 ...

  4. 根据浏览器判断是否为Android、ios或微信环境

    写h5页面时经常有业务逻辑需要判断页面所处的环境,这时我们可以通过navigator对象来获取浏览器相关信息加以判断,方法如下: let ua = navigator.userAgent; let i ...

  5. git 克隆 提交本地修改到远程方法

    最近一个项目,提交总报错 按照下面的流程就ok了 $ git clone $ git init $ cd shop $ git branch -al //查看所有分支 $ git pull origi ...

  6. python高级(一)—— python数据模型(特殊方法)

    本文主要内容 collections.namedtuple __getitem__ 和 __len__ __repr__和__str__ __abs__.__add__和__mul__ __bool_ ...

  7. Linux and Shell 实用命令

    -name '*.jar' -printf '%p:' ### 查看CPU使用率 mpstat -P ALL

  8. 使用Session监听器实现统计在线人数

    使用Session监听器实现统计在线人数 1.工作目录结构 包含监听器类和jsp页面 2.session监听器 首先利用session监听器来实现对访问网站时的session计数,当有session创 ...

  9. 关于DES加密强制更新版(4.22)

    数据加密算法(Data Encryption Algorithm,DEA)是一种对称加密算法,很可能是使用最广泛的密钥系统,特别是在保护金融数据的安全中,最初开发的DEA是嵌入硬件中的.通常,自动取款 ...

  10. Comparing deep learning frameworks: Tensorflow, CNTK, MXNet, & Caffe

    https://imaginghub.com/blog/10-a-comparison-of-four-deep-learning-frameworks-tensorflow-cntk-mxnet-a ...