继续学习代理模式:
我要找咱公司老总办事,可无奈,我认识他,他不认识我,无法直接找到他,这件事眼看就要黄。这时突然想起,咱之前给老总的秘书小刘跑过腿,咱可以试试通过小刘来帮我把礼送到老总那,看能不能同样把事情办好。这秘书小刘平常在公司就经常挂着个牌子,找老总办事,先通过我。。。
现实中,代理模式的例子举不胜举,比如销售代理也是最常见的一种,这里我们举一个电脑销售的例子,来简单的学习一下代理模式的核心思想。
一。提供一个公共接口,真实的对象(被代理对象)--电脑厂商以及代理对象--电脑代理商都具有销售掉闹的方法。
public interface SaleComputer { public void sale();}
二。真实对象(被代理对象)--电脑厂商,实现公共接口
public class ComputerMaker implements SaleComputer { public void sale() { System.out.println("电脑卖给你"); }}
三。代理对象--电脑代理商,也实现该接口,并持有被代理对象的一个引用,并在公共接口方法里调用真实对象的方法,并且增加自己的特有内容
public class ComputerProxy implements SaleComputer { private ComputerMaker maker; /*public ComputerMaker getMaker(){ if(null == maker){ maker = new ComputerMaker(); } return maker; }*///通常此方法对客户是不可见的,不然,咱直接就找电脑商买了~~ public void sale() { preSale(); if(null == maker){ maker = new ComputerMaker(); } maker.sale(); postSale(); } public void preSale(){ System.out.println("来代理商这里买就送你一个鼠标"); } public void postSale(){ System.out.println("代理商送你一个鼠标"); }}
四。客户端,测试一下
public class Client{ public static void main(String[] args) { ComputerProxy proxy = new ComputerProxy(); proxy.sale(); }}
以上是最简单的代理模式的一个例子了,但却也包含了代理模式的实质内涵。
接着是动态代理:被代理对象可以在运行时动态改变,需要控制的接口可以在运行时改变,控制的方式也可以动态改变,从而实现了非常灵活的动态代理关系。
动态代理的适用场合:调试;RMI调用
动态代理的创建步骤:1.创建一个实现java.lang.reflect.InvocationHandler接口的类,并实现invoke方法
2.创建被代理的类以及接口
3.通过java.lang.reflect.Proxy的静态方法newProxyInstance创建一个代理。
4.通过代理调用公共接口方法(会自动调用invoke方法)
我们仍然使用电脑代理商的例子:
1.创建一个实现InvocationHandler接口的代理手柄(ProxyHandler)
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class ProxyHandler implements InvocationHandler { private Object obj;//这里是Object类型的引用,使得在运行时动态加 //载被代理对象 public ProxyHandler(Object obj){ this.obj = obj; } public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable { String type = (String) arg2[0]; if("联想"==type||"华硕"==type){ preInvoke(); arg1.invoke(obj, arg2); postInvoke(); } else System.out.println("这里没有"+type+"牌子的电脑"); return null; } public void preInvoke(){ System.out.println("来代理商这里买就给送你一个鼠标"); } public void postInvoke(){ System.out.println("代理商送你一个鼠标"); }}
2.创建真实对象(ComputerMaker)和公共接口(SaleComputer)
public interface SaleComputer { public void sale(String type);}
public class ComputerMaker implements SaleComputer { public void sale(String type) { System.out.println("卖给你一台"+type+"电脑"); }}
3.创建一个客户端来测试
import java.lang.reflect.Proxy;public class Buyer { public static void main(String[] args) { ComputerMaker maker = new ComputerMaker(); Class<?> classType = maker.getClass(); ProxyHandler handler = new ProxyHandler(maker); SaleComputer proxy = (SaleComputer) Proxy.newProxyInstance(classType.getClassLoader(), classType.getInterfaces(), handler); proxy.sale("Dell"); }}
动态代理还是相当重要的,其实原理还是基于反射。