如A要租房,为了省麻烦A会去找中介,中介会替代A去筛选房子,A坐享中介筛选的结果,并且交房租也是交给中介,这就是一个典型的日常生活中代理模式的应用.
/** * 动态代理 * /** * 对于客户来说,完全不用跟House进行直接交互,这 * 里先定义一个房子叫唐顿庄园,租金5k,建立一个房屋代理, * 把唐顿庄园委托给代理.客户要找房子,签合同,付租金直接找代理就行了. */ public void testDongtaiMode(){ ProxyHandler proxy = new ProxyHandler(); IHouse house = (IHouse) proxy.newProxyInstance(new House("Downton Abbey", 5000)); Log.i(TAG, "looking for a perfect house"); house.getHouseInfo(); Log.i(TAG, "thinking"); house.signContract(); house.payFees(); Log.i(TAG, "so easy"); }
public class ProxyHandler implements InvocationHandler { private final String TAG = ProxyHandler.class.getSimpleName(); // 这个就是我们要代理的真实对象 Object targetObj; //构造方法,给我们要代理的真实对象赋初值 public Object newProxyInstance(Object targetObj) { this.targetObj = targetObj; return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), targetObj.getClass().getInterfaces(), this); } @Override public Object invoke(Object o, Method method, Object[] objects) throws Throwable { Object ret; //在代理真实对象前我们可以添加一些自己的操作 Log.i(TAG, "method name:" + method.getName()); //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用 ret = method.invoke(targetObj, objects);//对象,还有操作方法的参数 //在代理真实对象后我们也可以添加一些自己的操作 System.out.println("after rent house"); return ret; } }
/** * Created by Administrator on 2017/9/14. * 接下来定义真实主题,并实现IHouse接口.增加房屋名称和价格两个属性,填充借口方法, * 在获取房屋信息的时候就把房屋名称和价格log出来;签合同的时候log出签合同的时间,付租金的时候log出价格. */ public class House implements IHouse{ private final String TAG = House.class.getSimpleName(); private String name; private double price; public House(String name, double price){ this.name = name; this.price = price; } @Override public void getHouseInfo() { } @Override public void signContract() { } @Override public void payFees() { } }
/** * Created by Administrator on 2017/9/14. * 根据场景先定义一个抽象主题,IHouse,提供三个方法,分别是获取房屋信息,签合同和付租金. */ public interface IHouse { void getHouseInfo(); void signContract(); void payFees(); }
总结:
代理模式的组成:
Abstract Subject:抽象主题-声明真实主题和代理主题共同的接口
Real Subject:真实主题-真实的对象,需要被代理主题引用
Proxy Subject:代理主题(实现InvocationHandler)-可以在调用方法的前面和后面做一些事情(hook),
因为ProxySubject引用了RealSubject,并且实现了跟RealSubject一样的接口,所以ProxySubject可以操作RealSubject,还可以提供一些附加操作,例如before & after
代理的好处:可以抽取共同的部分,减少代码量!
代理作为调用着和真实对象的中间层,降低了模块间和系统的耦合性
用一个实现类
如果2个类的话,需要实现不同的功能的话。可以用2个不同的实现类
安卓用的代码模式