设计模式之代理模式

代理模式是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用,通俗的来讲代理模式就是我们生活中常见的中介。

打个比方说:我要买房,但是我对该地区房屋的信息掌握的不够全面,希望找一个更熟悉的人(中介)去帮我找,此处的代理就是这个意思。

代理类分为静态代理类和动态代理类:
在这里插入图片描述

静态代理

1.定义一个接口

public interface Source {  
  void method();
}

2.委托类

/**
 * 委托类
  */
  public class RealSubject implements Source {
    @Override    public void method() {
        System.out.println("我要去买房了");
    }
}

3.静态代理类

/**
 * 静态代理类
 */
 public class ProxySubject implements Source{ 
    private RealSubject realSubject;   
     public ProxySubject() {    
         this.realSubject = new RealSubject();
    }

    @Override    public void method() {
        before();
        realSubject.method();
        after();
    }    void before(){
        System.out.println("找房");
    }    void after(){
        System.out.println("买房后装修");
    }
}

测试类

public class Text {    public static void main(String[] args) {
        Source source = new ProxySubject();
        source.method();
    }
}

输出结果

找房
我要去买房了
买房后装修

静态代理总结:

优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。

缺点:我们得为每一个服务都创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。

动态代理类

动态代理类中我们不需要手动的创建代理类,我们只需要手动的编写一个动态处理器就可以了,真正的代理对象由JDK在运行时为我们动态的进行创建;

Dynamic代理模式相对于静态代理,大大减少了我们的开发任务,同时减少了对业务接口的依赖,降低了耦合度;

动态代理的实现依靠于InvocationHandler接口和Proxy类来实现的,每一个动态代理类中都必须要实现InvocationHandler接口,该接口中有唯一的invoke()方法;

该方法的作用就是得到一个动态的代理对象,其接收三个参数:

  • loader:第一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
  • interfaces:第二个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
  • h:第三个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上

代码演示

1.定义一个接口,有两个方法

public interface Source { 
   void describe();
   void buyHourse();
}

2.定义一个实现类(委托对象)

public class SourceImpl implements Source {
    @Override    public void describe() {
        System.out.println("中國風");
    }
    @Override    public void buyHourse() {
        System.out.println("购房");
    }
}

定义动态代理类,注意一定要实现接口 InvocationHandler

public class DynamicProxy implements InvocationHandler{    /**这个就是要代理的委托对象,使用Object类型,可以代理不同类型的对象,便于复用*/
    private Object source;    /**构造器,给要代理的对象赋值*/
    public DynamicProxy(Object source) {        this.source = source;
    }    /*
    我的理解:当我们通过动态代理对象调用委托对象的方法时会执行该方法     */
    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();        /*当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用*/
        method.invoke(source,args);
        after();        return null;
    }    void before(){
        System.out.println("调用对象方法前执行的业务逻辑");
    }    void after(){
        System.out.println("调用对象方法后执行的业务逻辑");
    }
}

测试类

public class Test {    public static void main(String[] args) {        //要代理的真实对象
        Source realSource = new SourceImpl();        //创建handler实例,我们要代理哪个对象就把该对象传进去,最后通过该真是对象来调用其方法
        InvocationHandler handler = new DynamicProxy(realSource);        /**
         * 通过Proxy.newProxyInstance方法来创建代理对象,
         * 第一个参数是目标对象的类加载器,获取方法为geiClassLoader()
         * 第二个参数是一个Interface对象的数组,表示的是将要给需要代理的对象提供一组什么借口,
         *     如果我提供了一组接口给它,那么这个代理对象就可以实现该接口(多态),
         *     这样就能调用这组接口中的方法了
         *     这里我们为代理对象提供的接口是真实对象所实行的接口,表示要代理的是该真是对象,
         *     这样就可以调用这组接口中的方法了
         * 第三个参数handler,指定的动态代理处理器,将该动态处理器传入真实的代理对象,即委托类对象         */
        Source source = (Source) Proxy.newProxyInstance(Source.class.getClassLoader(),
                realSource.getClass().getInterfaces(),handler);
        source.describe();
        System.out.println("");
        source.buyHourse();
    }
}

输出结果

调用对象方法前执行的业务逻辑
中國風
调用对象方法后执行的业务逻辑

调用对象方法前执行的业务逻辑
购房
调用对象方法后执行的业务逻辑

关注公众号【程序员每日一学】让我们每天一起学习进步~

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿小张丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值