A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© zlb820 中级黑马   /  2016-6-13 17:26  /  858 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

代理模式(proxy pattern)
定义:为其他的对象提供一种代理以控制对这个对象的访问。
代理模式 也称 委托模式,它是一项基本设计技巧,比如状态模式,策略模式,访问者模式本质上是在更特殊的场合采用了委托模式。
struts的form元素就采用了动态代理模式。

代理模式有三个角色:
1.subject抽象主题角色
抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义。
2.realsubject具体主题角色
即 被委托角色,被代理角色,是业务逻辑的具体执行者。
3.proxy代理主题角色
委托类,代理类。
一般情况下,一个代理类可以代理多个被委托者和被代理者,因此一个代理类具体代理哪个真实主题角色,是由场景类决定的。通常,一个接口只需要一个代理,具体代理哪个实现类由高层模块来决定,也就是在代理类的构造函数中传递被代理者。

代理模式的优点:
1.真实的角色就是实现实际的业务逻辑,不用关系其他的非本职责的事物,通过后期的代理完成一件事物,使得编成结构清晰。
2.高扩展性
具体的主题角色不论怎么变化,都不会影响到代理
3.智能化

使用场景:
springAop就是一个典型的动态代理

代理模式的扩展
在网络上把代理服务设置分为透明代理和普通代理,透明代理就是用户不用设置代理服务器的地址,可以直接访问,透明代理对用户来说是透明的,用户不用知道代理的存在。普通代理需要用户自己设置代理服务器的IP地址,用户必须知道代理服务器的地址。
1.普通代理
要求用户只能访问代理角色,不能访问真实角色。即只能通过代理来访问。
实现:通过在被代理者中的构造函数的限制,只有指定的方式才可以创建对象。
具体过程是:
场景类创建代理对象--在代理角色中创建真实角色对象(指定的构造)
2.强制代理
强制代理是由真实角色管理代理角色,即当高层模块new了一个真实角色的对象,但是返回的是代理角色。
必须通过真实角色指定的代理来进行访问,当然真实角色提供了获得他代理的对外接口方法。

真实角色内部创建好了代理角色,场景类通过真实对象调用即可。
3.代理有个性的
代理的目标是在目标对象的基础上进行增强,这种增强本质通常是对目标对象的方法进行拦截和过滤。
意思是:代理也可以有自己的运算方法,他的职责并不单一。代理类可以为真实角色处理消息,过滤消息,消息转发,事后处理等功能。一个代理类也可以代理多个真实角色,并且这些真实角色之间也可以有耦合。
4.虚拟代理
虚拟代理,重点是在需要的时候才初始化主体对象,类似懒汉模式。
5.动态代理
动态代理实在实现阶段不用关心代理谁,而在运行的阶段才指定代理的对象。相对而言,自己写代理的方式,就是静态代理。
主要应用jdk提供的动态代理接口InvocationHandler,进行代理。
通过InvocationHandler接口中的invoke方法来实现对真实方法的调用,给定一个接口,通过InvocationHandler接口,所有方法通过Handler来进行处理,所有被代理的方法交由InvocationHandler来接管实际的处理任务。

invoke方法:
public object invoke (Object proxy,Method method,Object[] args) throws Throwable{
            return method.invoke(this,args);
}
在动态代理调用时有这样一个方法:
s:真实角色对象
Proxy.newProxyInstance(s.getClassLoader(),c.getInterfaces(),new MyInvocationHandler(_obj));
c.getInterfaces()查找到该类的所有接口,并实现该接口的所有方法,但是方法都是空的,不像静态代理那样,我们自己写了方法的返回,间接调用了真实角色方法;动态代理是InvocationHandler实现类实现所有的方法,并由invoke接管所有方法的实现。

动态代理是横切面编程,在不改变已有代码结构的情况下增强或者控制对象的行为。
动态代理的前提是实现类必须实现一个接口,也有CGLIB不需要借口也能实现动态代理,springAop也是很好的动态代理。





0 个回复

您需要登录后才可以回帖 登录 | 加入黑马