代理模式的核心作用就是通过代理,控制对对象的访问。这跟实际中是一样的,比如说明星都有经纪人,这就是一个代理,比如有人要找某明星拍戏,那么首先处理这事的是他的经纪人,虽然拍戏需要自己拍,但是拍戏前后的一些必须要做的事等等,都由这个经纪人来处理。 
  在程序中也是如此,通过代理,可以详细控制访问某个或者某类对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。这也是AOP的实现原理。 
  那么代理模式的核心角色该如何设计呢?

设计思路:定义一个抽象角色,让代理角色和真实角色分别去实现它。 
1. 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。它只关注真正的业务逻辑,比如拍戏。 
2. 代理角色:实现抽象角色,是真实角色的代理,通过真是角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作,比如谈合同,布置场地等等。

  下面来具体实现这个代理模式,代理模式分为静态代理和动态代理。静态代理是我们自己创建一个代理类,而动态代理是程序自动帮我们生成一个代理,我们就不用管了。

1. 静态代理

根据上面的实现步骤,首先来写一个抽象角色:

/**
* @Description 接口类
* @author shanheyongmu
*
*/
public interface Star { public void confer(); //面谈
public void sing(); //唱歌
public void collectMoney(); //收钱
}

这个抽象类中有三个方法,现在分别让真实角色和代理角色来实现该抽象类:

/**
* @Description 真实对象
* @author shanheyongmu
*
*/
public class RealStar implements Star { @Override
public void confer() {
System.out.println("RealStar.confer()");
} @Override
public void sing() {
System.out.println("RealStar(周杰伦).sing()");
} @Override
public void collectMoney() {
System.out.println("RealStar.collectMoney()");
} }

唱歌部分,注明一下周杰伦,等会好区分。下面再来看下代理类。

/**
* @Description 代理类
* @author shanheyongmu
*
*/
public class ProxyStar implements Star { private Star star; public ProxyStar(Star star) { //到时候传进来真实的star
super();
this.star = star;
} @Override
public void confer() {
System.out.println("ProxyStar.confer()");
} @Override
public void sing() {
//其他事都能干,唯一不能干的就是唱歌,唱歌还是得要周杰伦本人来唱
star.sing(); //让他本人来唱
} @Override
public void collectMoney() {
System.out.println("ProxyStar.collectMoney()");
} }

在代理类中,可以看到,维护了一个Star对象,通过构造方法传进来一个真实的Star对象给其赋值,然后在唱歌这个方法里,使用真实对象来唱歌。所以说面谈、收钱都是由代理对象来实现的,唱歌是代理对象让真实对象来做。 
下面写个客户端的测试用例:

public class Client {

    public static void main(String[] args) {
Star real = new RealStar();
Star proxy = new ProxyStar(real); proxy.confer();
proxy.sing();
proxy.collectMoney();
} }

输出结果:

ProxyStar.confer() 
RealStar(周杰伦).sing() 
ProxyStar.collectMoney()

可以看出,客户端只跟代理对象打交道,代理对象把能做的都做了,比如面谈和收钱,唱歌呢,是调用真实对象去唱。

2. 动态代理

  动态代理比静态代理使用的更广泛,动态代理在本质上,代理类不用我们来管,我们完全交给工具去生成代理类。Star接口和RealStar实现类还是和上面的一样,下面来定义一下代理类,使用动态代理需要实现InvocationHandler接口,并覆写里面的invoke方法,如下:

/**
* @Description 动态代理类
* @author shanheyongmu
*
*/
public class StarHandler implements InvocationHandler { Star realStar; public StarHandler(Star realStar) {
super();
this.realStar = realStar;
} @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable { Object object = null; // 在代理真实对象前,我们可以做些自己的操作
System.out.println("面谈"); if(method.getName().equals("sing")) {
object = method.invoke(realStar, args);
} // 在代理真是对象后,我们可以做些自己的操作
System.out.println("收钱"); return object;
} }

可以看出,思路和静态代理是一样的,先通过构造方法把真正的对象传进来,然后执行代理的部分是invoke方法中,在该方法中,我们进行一次判断,只有当需要唱歌的时候,我就调用刚刚传进来的真实对象来唱,其他事情由代理代替真实对象来做,这里只用控制台输出来模拟一下。 
  最后来写个客户端测试一下:

public class Client {

    public static void main(String[] args) {

        Star realStar = new RealStar();
StarHandler handler = new StarHandler(realStar); //创建代理类
Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler); proxy.sing();
} }

看下控制台输出:

面谈 
RealStar(周杰伦).sing() 
收钱

  由此可见,使用代理可以在执行某个逻辑的前后加上新的逻辑,这是很好的功能,实际中spring的AOP用的就是这种技术。

 

【java设计模式】之 代理(Proxy)模式的更多相关文章

  1. JAVA设计模式-动态代理(Proxy)示例及说明

    在Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析文章的最后部分,我们提到了动态代理的概念,下面我们就简单了解一下动态代理. 一,概念 代理设计模式的目的就是在不直接操作对象的前 ...

  2. JAVA设计模式-动态代理(Proxy)源码分析

    在文章:JAVA设计模式-动态代理(Proxy)示例及说明中,为动态代理设计模式举了一个小小的例子,那么这篇文章就来分析一下源码的实现. 一,Proxy.newProxyInstance方法 @Cal ...

  3. Head First 设计模式 —— 13. 代理 (Proxy) 模式

    思考题 如何设计一个支持远程方法调用的系统?你要怎样才能让开发人员不用写太多代码?让远程调用看起来像本地调用一样,毫无瑕疵? P435 已经接触过 RPC 了,所以就很容易知道具体流程:客户端调用目标 ...

  4. 十、设计模式之代理(Proxy)模式

    什么是代理模式 代理模式是对象的结构模式,为其他对象提供一种对象以控制对这个对象的访问. 代理模式的结构图如下:(源自大话设计模式)   Subject:定义了RealSubject和Proxy的公共 ...

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

    为什么这里要定义代理呢?所谓代理代理,当然就是你不想做的事.找别人去做,这就是代理.所以,当你写代码的时候.你想保持类的简单性.重用性.你就能够把事件尽量都交给其他类去做.自己仅仅管做好自己的事.也就 ...

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

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

  7. java设计模式6——代理模式

    java设计模式6--代理模式 1.代理模式介绍: 1.1.为什么要学习代理模式?因为这就是Spring Aop的底层!(SpringAop 和 SpringMvc) 1.2.代理模式的分类: 静态代 ...

  8. java --- 设计模式 --- 动态代理

    Java设计模式——动态代理 java提供了动态代理的对象,本文主要探究它的实现, 动态代理是AOP(面向切面编程, Aspect Oriented Programming)的基础实现方式, 动态代理 ...

  9. Java设计模式系列-装饰器模式

    原创文章,转载请标注出处:<Java设计模式系列-装饰器模式> 一.概述 装饰器模式作用是针对目标方法进行增强,提供新的功能或者额外的功能. 不同于适配器模式和桥接模式,装饰器模式涉及的是 ...

  10. 【设计模式】Java设计模式 - 动态代理

    [设计模式]Java设计模式 - 动态代理 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 最近工作比较忙,没啥时间学习 目录 [设计模 ...

随机推荐

  1. Gson全解析(上)-Gson基础

    前言 最近在研究Retrofit中使用的Gson的时候,发现对Gson的一些深层次的概念和使用比较模糊,所以这里做一个知识点的归纳整理. Gson(又称Google Gson)是Google公司发布的 ...

  2. mac的cpu处理器个数、核数、超线程

    处理器:1个 每个核的L2缓存大小:256KB L3缓存大小:3MB 核数:2个 2个核却有4个CPU:使用了超线程技术--双核四线程 macOS,查看CPU信息:sysctl machdep.cpu ...

  3. 【BZOJ】【3053】The Closest M Points

    KD-Tree 题目大意:K维空间内,与给定点欧几里得距离最近的 m 个点. KD树啊……还能怎样啊……然而扩展到k维其实并没多么复杂?除了我已经脑补不出建树过程……不过代码好像变化不大>_&g ...

  4. unity 3D游戏场景转换

    //////////////////2015/07/07//////// /////////////////by xbw/////////////// ///////////////环境 unity ...

  5. cocos2dxHellowoed 发现 2.2.3

    cocos2d 笔记 文件夹介绍 cocosdx ----->cocos2d主要代码 CocosDenshion---->cocos2d的声音的 Document------>文档 ...

  6. python中的exec()、eval()以及complie()

    参考博客:http://www.cnblogs.com/yyds/p/6276746.html 1.eval函数 函数的作用: 计算指定表达式的值.也就是说它要执行的python代码只能是单个表达式( ...

  7. CentOS 7上安装WordPress详细步骤

    一.搭建Wordpress服务器环境需求: php 5.2.4 或者更高版本.MySQL 5.0 或者更高版本. 二.搭建Wordpress平台:以下以Wordpress3.92版本为例进行说明,如果 ...

  8. 如何配置Ubuntu 16.04 GRUB 2引导加载程序

    正如你所知,GRUB 2 是大多数 Linux 操作系统的默认引导加载程序.GRUB 是 GRand Unified Bootloader 的缩写,它是 Linux 启动时首先要加载的一个程序,此后它 ...

  9. 【转载】oracle更新语法

    oracle更新语法:1.一般语法   update tab set col = .... [where ...]   =后可以有子查询,但是必须对于tab的每一列返回唯一一行与之对应,where是需 ...

  10. poj 2391 (Floyd+最大流+二分)

    题意:有n块草地,一些奶牛在草地上吃草,草地间有m条路,一些草地上有避雨点,每个避雨点能容纳的奶牛是有限的,给出通过每条路的时间,问最少需要多少时间能让所有奶牛进入一个避雨点. 两个避雨点间可以相互到 ...