代理模式(Proxy Pattern)也叫做委托模式,是一个使用率非常高的模式。

定义如下:
     为其他对象提供一种代理以控制对这个对象的访问。

个人理解:

       代理模式将原类进行封装,客户端不能直接找到原类,必须通过代理角色。即代理是原类的一个替身,客户端要找原类,统统找代理就可以搞定。明星和经纪人就是一种代理模式。

通用类图如下:

角色定义:

● Subject 抽象主题角色
     抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。

● Real Subject 具体主题角色

也叫做被委托角色、被代理角色。它才是冤大头,是业务逻辑的具体执行者。

● Proxy代理主题角色
    也叫做委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。

通用源代码:

//抽象主题类
public interface Subject {
//定义一个方法
public void request();
}

在接口中我们定义了一个方法request来作为方法的代表,RealSubject对它进行实现。

//真实主题类
public class Real Subject implements Subject {
//实现方法
public void request() {
//业务逻辑处理
}
}

Real Subject是一个正常的业务实现类,代理模式的核心就在代理类上。

代理类如下:

public class Proxy implements Subject {
//要代理哪个实现类
private Subject subject = null;
//默认被代理者
public Proxy(){
this.subject = new Proxy();
}
//通过构造函数传递代理者
public Proxy(Object...objects ) {
}
//实现接口中定义的方法
public void request() {
this.before();
this.subject.request();
this.after();
}
//预处理
private void before(){
//do something
}
//善后处理
private void after(){
//do something
}
}

代理模式的优点:

职责清晰、高扩展性、智能化

案例分析:追星族想要明星签名,必须找其经纪人搞定。

类图如下:

 

通用源代码如下:

//明星接口
public interface IStar {
//明星都会签名
public void sign();
}
//明星只有一个行为:签字。我们来看明星的实现,如代码清单3 //明星
public class Singer implements IStar {
public void sign() {
System.out.println("明星签字:我是XXX大明星");
}
} //经纪人与明星应该有相同的行为,比如说签名,虽然经纪人不签名,但是他把你要签名的笔记本、衣服、CD等传递过去让真正的明星签字, //经纪人
public class Agent implements IStar {
//定义是谁的经纪人
private IStar star;
//构造函数传递明星
public Agent(IStar _star){
this.star = _star;
}
//经纪人是不会签字的,签字了歌迷也不认
public void sign() {
star.sign();
}
}
//追星族
public class Idolater {
public static void main(String[] args) {
//崇拜的明星是谁
IStar star = new Singer();
//找到明星的经纪人
IStar agent = new Agent(star);
System.out.println("追星族:我是你的崇拜者,请签名!");
//签字
agent.sign();
}
}

很简单,找到明星的代理,然后明星就签字了。运行结果如下所示:

追星族:我是你的崇拜者,请签名!
明星签字:我是XXX大明星

看看我们的程序逻辑,我们是找明星的经纪人签字,真实签字的是明星,经纪人只是把这个请求传递给明星处理而已,这是普通的代理模式的典型应用。

 

 *********************************************************************************************************************************************************************

 代理模式的扩展:

 普通代理、强制代理、动态代理

普通代理:要求客户端只能访问代理角色,而不能访问真实角色。

在该模式下,调用者只知道代理而不知道真是的角色是谁,屏蔽了真是角色的变更对高层模块的影响,真实的主

题角色想怎么修改都可以。在实际项目中,一般通过约定来禁止new一个真实的角色。

强制代理:客户端必须通过真实角色查找到代理角色,否则你不能访问。

就好比是你和一个明星比较熟,相互认识,有件事情你需要向她确认一下,于是你就直接拨通了明星的电话:
                  “喂,沙比呀,我要见一下×××导演,你帮下忙了!”
                 “不行呀衰哥,我这几天很忙呀,你找我的经纪人吧……”

郁闷了吧,你是想直接绕过她的代理,谁知道返回的还是她的代理,这就是强制代理,你可以不用知道代理存在,但是你的所作所为还是需要代理为你提供。

 动态代理:

     在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象。相对来说,自己写代理类的方式就是静态

代理。

首先我们需要学习JDK提供的动态代理接口InvocationHandler,该接口对被代理类的方法进行代理。

JDK如图所示:

其次还有一个类叫Proxy,来看JDK描述,我们主要使用了newProxyInstance( )的静态方法。

动态代理Demo如下:

package com.package1;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class DynamicProxy { public static void main(String[] args){
//定义一个people作为被代理的实例
IPeople ple=new People();
//定义一个handler
InvocationHandler handle=new MyHandle(ple); //获得类加载器
ClassLoader cl=ple.getClass().getClassLoader(); //动态产生一个代理,下边两种方法均可
// IPeople p=(IPeople) Proxy.newProxyInstance(cl, new Class[]{IPeople.class}, handle);
IPeople p=(IPeople) Proxy.newProxyInstance(cl, ple.getClass().getInterfaces(), handle); //执行被代理者的方法。
p.func();
} } class MyHandle implements InvocationHandler{ //被代理的实例
Object obj=null; //我要代理谁
public MyHandle(Object obj){
this.obj=obj; } @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result=method.invoke(this.obj, args);
return result;
} } interface IPeople{ public void fun(); public void func();
} //实际被代理的类
class People implements IPeople{ @Override
public void fun() {
System.out.println("这是fun方法"); } @Override
public void func() {
System.out.println("这是func方法"); } }

其中invoke方法是接口Invocation Handler定义必须实现的,它完成对真实方法的调用。我们来详细讲解一下Invocation Handler

接口,动态代理是根据被代理的接口生成所有的方法,也就是说给定一个接口,动态代理会宣称“我已经实现该接口下的所有方法

了”,那各位读者想想看,动态代理怎么才能实现被代理接口中的方法呢?默认情况下所有的方法返回值都是空的,是的,代理已经

实现它了,但是没有任何的逻辑含义,那怎么办?好办,通过Invocation Handler接口,所有方法都由该Handler来进行处理,即所

有被代理的方法都由Invocation Handler接管实际的处理任务。

Java设计模式—代理模式的更多相关文章

  1. Java设计模式-代理模式之动态代理(附源代码分析)

    Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...

  2. JAVA 设计模式 代理模式

    用途 代理模式 (Proxy) 为其他对象提供一种代理以控制对这个对象的访问. 代理模式是一种结构型模式. 结构

  3. Java设计模式の代理模式

    目录  代理模式 1.1.静态代理   1.2.动态代理 1.3.Cglib代理 代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是 ...

  4. Java设计模式 - 代理模式

    1.什么是代理模式: 为另一个对象提供一个替身或占位符以访问这个对象. 2.代理模式有什么好处: (1)延迟加载 当你需要从网络上面查看一张很大的图片时,你可以使用代理模式先查看它的缩略图看是否是自己 ...

  5. Java设计模式——代理模式实现及原理

    简介 Java编程的目标是实现现实不能完成的,优化现实能够完成的,是一种虚拟技术.生活中的方方面面都可以虚拟到代码中.代理模式所讲的就是现实生活中的这么一个概念:中介. 代理模式的定义:给某一个对象提 ...

  6. Java设计模式-代理模式(Proxy)

    其实每个模式名称就表明了该模式的作用,代理模式就是多一个代理类出来,替原对象进行一些操作,比如我们在租房子的时候回去找中介,为什么呢?因为你对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人去帮你 ...

  7. Java设计模式--代理模式+动态代理+CGLib代理

    静态代理 抽象主题角色:声明真实主题和代理主题的共同接口. 代理主题角色:代理主题内部含有对真实主题的引用,从而在任何时候操作真实主题对象:代理主题提供一个与真实主题相同的接口,以便在任何时候都可以代 ...

  8. Java设计模式——代理模式

    public interface People { public void work(); } public class RealPeople implements People { public v ...

  9. Java 之 设计模式——代理模式

    设计模式——代理模式 一.概述 1.代理模式 (1)真实对象:被代理的对象 (2)代理对象:代理真实对象的 (3)代理模式:代理对象代理真实对象,达到增强真实对象功能的目的 二.实现方式 1.静态代理 ...

随机推荐

  1. JavaIO系统

    为了方便记忆,特将IO中涉及的类进行整理如下: 1.File类 提供了目录操作,查看文件属性等. 2.java IO类层次 面向字节流的类为InputStream.OutputStream:面向字符流 ...

  2. C#-WebForm-LinQ(一)-LinQ:语言集成查询(Language Integrated Query)-增删改查、属性扩展

    LinQ-语言集成查询(Language Integrated Query) 高集成化的数据库访问技术 LINQ 2 SQL 实际是将数据库的表映射成程序中的类 会把数据库的表名原封不动的变成类名 数 ...

  3. 钩子编程(HOOK) 屏蔽全部按键、鼠标及系统功能键 (4)

    摘要:上篇文章<钩子编程(HOOK) 安装系统全局钩子>已经具体的解说了全局钩子的安装.本文将增强一下钩子的功能.实现屏蔽全部按键鼠标与系统功能键.要实现这个功能.须要安装两个全局钩子,& ...

  4. 基于wavesurfer.js的超大音频的渐进式请求实现

    最近在对超大音频的渐进式请求实现上面消耗了不少时间,主要是因为一对音频的基本原理不太理解,二刚开始的时候太依赖插件,三网上这块的资料找不到只能靠自己摸索.由于交互复杂加上坑比较多,我怕描述不清,这里主 ...

  5. 下载 CentOS 7 镜像文件

    CentOS 7 镜像文件的下载地址 CentOS 官网:https://www.centos.org/ 点击“Get CentOS Now” 点击想要下载的ISO镜像,(目前仅有“DVD ISO”和 ...

  6. Codeforces - 149D 不错的区间DP

    题意:有一个字符串 s. 这个字符串是一个完全匹配的括号序列.在这个完全匹配的括号序列里,每个括号都有一个和它匹配的括号 你现在可以给这个匹配的括号序列中的括号染色,且有三个要求: 每个括号只有三种情 ...

  7. django.core.exceptions.ImproperlyConfigured: The SECRET_KEY setting must not be empty

    https://www.e-learn.cn/content/wangluowenzhang/165461 问题: I created a new project in django and past ...

  8. 深入了解Looper、Handler、Message之间关系

    深入了解Looper.Handler.Message之间关系 前言及简介 上个星期我们整个项目组趁着小假期,驱车去了江门市的台山猛虎峡玩了两个多钟左右极限勇士全程漂流,感觉真得不错,夏天就应该多多玩水 ...

  9. Spring Security OAuth 2开发者指南译

    Spring Security OAuth 2开发者指南译 介绍 这是用户指南的支持OAuth 2.0.对于OAuth 1.0,一切都是不同的,所以看到它的用户指南. 本用户指南分为两部分,第一部分为 ...

  10. UI的线程问题:单线程原因及更新UI的四种方式

    1.UI线程为什么设计为单线程? UI控件的操作不是线程安全的,对于多线程并发访问的时候,如果使用加锁机制会导致: UI控件的操作变得很复杂. 加锁的操作必定会导致效率下降. 所以android系统在 ...