欢迎来到Doc100.Net免费学习资源知识分享平台!
您的位置:首页 > 程序异常 >

java设计形式之代理模式(结构型模式)

更新时间: 2014-05-15 01:07:25 责任编辑: Author_N3

 

java设计模式之代理模式(结构型模式)

 

 

(8).代理模式:

文章链接:http://www.iteye.com/topic/517835

代理模式:给某一对象提供代理对象,并由代理对象控制具体对象的引用. 

 

代理,指的就是一个角色代表另一个角色采取行动,就象生活中,一个红酒厂商,是不会直接把红酒零售客户的,

都是通过代理来完成他的销售业务的.而客户,也不用为了喝红酒而到处找工厂,他只要找到厂商在当地的代理就行了,

具体红酒工厂在那里,客户不用关心,代理会帮他处理. 

代理模式涉及的角色: 

1:抽象主题角色.声明了代理主题和真实主题的公共接口,使任何需要真实主题的地方都能用代理主题代替. 

2:代理主题角色.含有真实主题的引用,从而可以在任何时候操作真实主题,代理主题功过提供和真实主题相同的接口,

使它可以随时代替真实主题.代理主题通过持有真实主题的引用,

不但可以控制真实主题的创建或删除,可以在真实主题被调用前进行拦截,或在调用后进行某些操作. 

3:真实代理对象.定义了代理角色所代表的具体对象. 

java主要是通过Proxy类和InvocationHandler接口来给实现对代理模式的支持的. 

,拦截机制是代理模式的重要使用方式之一, 

除了拦截,代理模式还常用于资源加载,当我们要加载的资源很大时,我们可以让真实主题角色在后台加载资源,让代理主题角色负责处理前台的等待提示信息. 

还有就是授权机制,通过代理能拦截真实主题的能力,来控制真实主题的访问权限.

讲到代理常常要讲到动态代理, 

如果代理是静态的,那么看起来和装饰器无二,所以代理常常都和动态以及反射联系在一起,总是和语言本身的能力有关…… 

代理模式通常是对原有对象的控制,不会增加新的行为,比如说原来干什么还是干什么,常见的比如cglib加上事务机制,但是没有增加新的行为,原有的服务未变。 

但是装饰模式通常会加上新的行为,而且行为可以动态进行组合,可以有任意顺序,比如给墙刷颜色,先刷底色,再刷红色,再刷绿色,也可以先刷底色,

再刷绿色,再刷红色。 

代理模式和装饰模式都可以构造成在新类中引用对原有类,构成原有类的委托,这样就可以对原有类进行控制了,可以加新的行为,也可以加上其他控制。 

不过有一点疑问,代理者和被代理者是聚合关系吗??聚合关系是整体和局部的关系,但是离开整体局部还可以生存,比如飞机场和飞机,

代理模式两者关系,我觉得应该是依赖关系,更像是user-a关系,正因为是依赖关系,所以我们使用接口进行了解耦,而不是显示依赖直接注入实现类 

package com.createtype.desginpatterns.proxy; public interface SellInterface { public Object sell(); } package com.createtype.desginpatterns.proxy; /** *代理主题角色,这里指红酒代理商.它除了也要实现了sellInterface接口外,还持有红酒 厂商RedWineFactory * 对象的引用,从而使它能在调用真实主题前后做一些必要处理. */ public class RedWineProxy implements SellInterface { // 持有一个RedWineFactory对象的引用 private RedWineFactory redWineFactory; // 销售总量 private static int sell_count = 0; public Object sell() { if (checkUser()) {// 在通过代理主题角色,我们可以在真实主题角色被调用前做一些诸如权限判断的事情 Object obj = redWineFactory.sell(); // count ++;//同样,在调用后我们也可以执行一些额外的动作. return obj; } else { throw new RuntimeException(); } } protected boolean checkUser() { // do something return true; } public static void main(String agr[]) { SellInterface sell = new RedWineProxy(); sell.sell(); } } package com.createtype.desginpatterns.proxy; /** *真实主题角色,这里指红酒工厂角色,它实现了SellInterface接口 *我们可以为他们定义一个共同的抽象主题角色, 接着,我们定义真实主题角色(这里就是红酒工厂),它必须实现了SellInterface接口的. */ public class RedWineFactory implements SellInterface{ public Object sell(){ System.out.println("真实主题角色RedWineFactory 被调用了"); return new Object(); } } package com.createtype.desginpatterns.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** *代理类一定要实现了InvocationHandler接口 */ public class ProxyObject implements InvocationHandler { private Object proxy_obj; ProxyObject(Object obj) { this.proxy_obj = obj; } public static Object factory(Object obj) { Class cls = obj.getClass(); // 通过Proxy类的newProxyInstance方法来返回代理对象 return Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), new ProxyObject(obj)); } /** *实现InvocationHandler接口的invoke */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("函数调用前被拦截了: " + method); if (args != null) { // 打印参数列表 System.out.println("方法有 " + args.length + " 个参数"); for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } } // 利用反射机制动态调用原对象的方法 Object mo = method.invoke(proxy_obj, args); System.out.println("函数调用后进行处理 : " + method); return mo; } // 测试代码 public static void main(String agr[]) { SellInterface si = (SellInterface) factory(new RedWineFactory()); si.sell(); } }  
上一篇:上一篇
下一篇:下一篇

 

随机推荐程序问答结果

 

 

如对文章有任何疑问请提交到问题反馈,或者您对内容不满意,请您反馈给我们DOC100.NET论坛发贴求解。
DOC100.NET资源网,机器学习分类整理更新日期::2014-05-15 01:07:25
如需转载,请注明文章出处和来源网址:http://www.doc100.net/bugs/t/328744/
本文WWW.DOC100.NET DOC100.NET版权所有。