前言
今天学习一代理模式,代理模式也是一种很常见的模式。简单记录学习中看到内容,方便自己后续查阅和回顾。
正文
代理模式
为一个对象提供一个替身,以控制对这个对象的访问。即通过代理对象访问目标对象。
代理模式分为静态代理和动态代理。
静态代理
静态代理在使用时 , 需要定义接口或者父类 , 目标对象与代理对象一起实现相同的接口或者是继承相同父类。
关键角色:
接口或父类
目标对象(也就是被代理的对象)
代理对象
demo
以客户点外卖为例,点了需要去哪,但客户就是不想去店里拿,所以需要有外卖员。
接口
也就是配送接口
public interface IFoodDelivery { void foodDelivery(); }
目标对象
也就是顾客。
顾客也可以配送自己的外卖,也需要实现配送接口。
public class Customer implements IFoodDelivery{ @Override public void foodDelivery() { //顾客拿外卖 } }
代理对象
外卖员。
顾客不想走路,因此外卖员帮忙拿外卖。
/** * 外卖员,也就是顾客的代理人 */ public class Deliveryman implements IFoodDelivery { private final IFoodDelivery iFoodDelivery; public Deliveryman(IFoodDelivery iFoodDelivery) { this.iFoodDelivery = iFoodDelivery; } @Override public void foodDelivery() { iFoodDelivery.foodDelivery(); } }
客户端
Customer customer = new Customer(); Deliveryman deliveryman = new Deliveryman(customer); deliveryman.foodDelivery();
优缺点
优点
在不修改目标对象的功能前提下 , 能通过代理对象对目标功能扩展
缺点
代理对象需要与目标对象实现一样的接口 , 所以会有很多代理类
一旦接口增加方法 , 目标对象与代理对象都要维护
动态代理
动态代理其实本质上将被代理类包装一层,生成一个具有新的相同功能的代理类。
通过java提供的Proxy
类帮我们创建代理对象。
特点:
代理对象,不需要实现接口
代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要指定创建代理对象/目标对象实现的接口的类型)
动态代理也叫做:JDK代理,接口代理
相对于静态代理,动态代理不需要代理对象实现接口。
优缺点
代理对象不需要实现接口,但是目标对象一定要实现接口,否则不能用动态代理。
demo
接口
也就是配送接口
public interface IFoodDelivery { void foodDelivery(); }
目标对象
也就是顾客。
顾客也可以配送自己的外卖,也需要实现配送接口。
public class Customer implements IFoodDelivery{ @Override public void foodDelivery() { //顾客拿外卖 } }
代理对象
主要通过
1. ClassLoader loader : 指定当前目标对象使用的类加载器, 获取加载器的方法固定 2. Class<?>[] interfaces: 目标对象实现的接口类型,使用泛型方法确认类型 3. InvocationHandler h : 事情处理,执行目标对象的方法时,会触发事情处理器方法, 会把当前执行的目标对象方法作为参数传入 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
下面是客户代理类。
public class CustomerProxy { private final Object object; public CustomerProxy(Object object){ this.object = object; } public Object getProxyInstance(){ return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(object, args); } }); } }
客户端
Customer customer = new Customer(); IFoodDelivery iFoodDelivery = (IFoodDelivery) new CustomerProxy(customer).getProxyInstance(); iFoodDelivery.foodDelivery();
参考文章
《》
《》
《
© 版权声明