java设计模式-代理模式

hl.wang

发布于 2019.09.23 11:16 阅读 2486 评论 0

代理模式

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

 

为何要使用?

1、在某些情况下,一个客户类不想或者不能直接引用一个委托对象

2、给项目加入缓存、日志这些功能

 

 

如何使用?

 

代理模式分为静态代理模式和动态代理模式,首先我们来看一下静态代理模式。

我用就拿一个粉丝想要明星的签名为例子来用静态代理模式实现一下

 

 

首先编写明星接口

public interface Star {
    void seal();
}

 

然后明星实现这个接口

public class Singer implements Star {
    @Override
    public void seal() {
        System.out.println("拿到歌手签名");
    }
}

 

 

 

 

       大家知道要直接和明星本人要签名是比较难得。那样粉丝那么多明星也就累死了,但是明星都是有经纪人的,我们像经纪人要明星的签名就会比较容易得多,所以我们来创建一个明星经纪人的类

public class SingerAgent implements Star {
    @Override
    public void seal() {
        new Singer().seal();
    }
}

 

其实到这里就已经完成了,是不是很简单呢。

 

 

 

下面我们来看一下动态代理模式,这里我使用的时候jdk动态代理

public class TimeHandler implements InvocationHandler {
    private SingerAgent singerAgent;
    public TimeHandler(SingerAgent singerAgent){
        this.singerAgent = singerAgent;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result = null;
        result = method.invoke(singerAgent,args);
        return result;
    }
}

 

 

invoke方法里用来存放具体的逻辑实现,因此本例中没有什么逻辑实现因此就没有编写。

 

下面我们来测试一下这两种代理模式

public class Demo {
    public static void main(String[] args) {
        //静态代理模式
        Star star = new SingerAgent();
        star.seal();
        //动态代理模式
        SingerAgent singerAgent  = new SingerAgent();
        TimeHandler timeHandler = new TimeHandler(singerAgent);
        star = (Star) Proxy.newProxyInstance(Demo.class.getClassLoader(),singerAgent.getClass().getInterfaces(),timeHandler);
        star.seal();
    }
}

 

 

总结

静态代理:

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

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

动态代理:

       动态代理大大减少了我们的开发任务,同时减少了对业务接口的依赖,降低了耦合度。但是还是有一点点小小的遗憾之处,那就是它始终无法摆脱仅支持interface代理的桎梏,因为它的设计注定了这个遗憾。