代理模式学习

代理模式

代理模式是结构型模式,相当于给一个对象生成一个代理对象,我们去访问的时候直接面对的是代理对象。在平时的生活中也有类似的例子,比如房产中介,我们在租房的时候面对的不是真正的房东而是中介,这个中介就相当于房东的代理对象。代理对象可以对原对象的功能进行增强。下面通过一张图来展示下代理模式。

在上图中,我们可以看到代理类和被代理类都需要继承同一个接口,然后代理类又继承了被代理类,这样就可以对被代理类进行功能增强。然后我们用户访问的是代理类。

代理类型的分类:

  • 静态代理
  • 动态代理

静态代理

静态代理:相当于提前实现好代理类,在需要的时候直接创建实例即可。静态代理存在一些局限,比如一些被代理类需要相同的功能增强逻辑,静态代理就需要一个个去实现这些类的代理类,非常的麻烦,编码量大,同时也不易管理。

静态代理代码实现

场景描述:用户去租房,租房找的都是中介而并非房东

  1. 实现租房接口
//租房接口
public interface Rent {
    void rentHouse();
}
  1. 房东类的实现(也就是被代理类),需要实现接口
//房东类实现了租房的接口
public class Host implements Rent {
    @Override
    public void rentHouse() { 
        System.out.println("我是房东,我要出租房子");
    } 
}
  1. 中介类的实现(也就是代理类),需要实现接口
//中介类,同样实现了租房接口,并且需要加入房东类,调用房东类中的功能
public class RentProxy implements Rent {
    private Host host;
    public RentProxy(Host host) {
        this.host = host;
    }
    @Override
    public void rentHouse() { 
        System.out.println("我是中介,带着客户去看房子"); host.rentHouse();
    } 
}
  1. 测试代码
public class ProxyTest {
    public static void main(String[] args) {
        //调用中介的租房方法
        RentProxy proxy = new RentProxy(new Host()); 
        proxy.rentHouse();
    }
}

动态代理

动态代理,相对于静态代理来说就是代理类是动态生成的而不是提前编码好。动态代理,减少了编码量以及方便管理。这里动态代理的实现是基于接口的实现。动态代理的有两种常见的实现:

  • Jdk动态代理:基于接口的实现。
  • cglib动态代理:基于类的实现。

下面的代码实现是基于接口的实现,也就是jdk动态代理

动态代理代码实现

  1. 同静态代理第一步:实现租房接口
  2. 同静态代理第二步:实现房东类
  3. 实现代理handler,这里没有实现代理类,区别于静态代理
//实现代理handler
public class RentProxyHandler implements InvocationHandler {
    private Object rent;
    public RentProxyHandler(Object rent) {
        this.rent = rent;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws
            Throwable {
        //功能增强
        System.out.println("中介带着客户去看房子"); 
        //调用被代理类中的方法
        method.invoke(rent,args);
        return null;
    } 
}
  1. 测试代码
public class ProxyTest {
    public static void main(String[] args) {
        //创建需要被代理的对象,这里就是房东
        Host host = new Host();
        //创建代理handller,然后将需要被代理的对象传入到handller中
        RentProxyHandler proxyHandler = new RentProxyHandler(host);
        //这里用于动态的生成代理对象,也就是相当于我们之前写RentProxy,不过这里我们是自动生成的
        Rent rentProxy = (Rent) Proxy.newProxyInstance(host.getClass().getClassLoader(),
                        host.getClass().getInterfaces(), proxyHandler);
        rentProxy.rentHouse();
    }
}
posted @ 2020-09-20 16:30  un1que~  阅读(103)  评论(0编辑  收藏  举报