设计模式 -- 代理模式

「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

含义: 通过代理的方式对其他对象进行访问。

顾名思义就是别人代理你去做一些事情,下面就是买咖啡的一个例子,老板想喝咖啡了,老板这么忙,当然不能自己跑腿了,所以他就吩咐自己的秘书去做这件事情,这时候老板就是被代理的类,秘书就是代理类。

代理模式按照创建时期可以分成静态代理动态代理两种,下面这种是是静态代理静态代理是在运行之前就创建代理类。代理对象持有被代理对象的引⽤,调⽤代理对象⽅法时也会调⽤被代理对象的⽅法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
java复制代码 public interface BuyCoffee{
     void buyCoffee();
 }
 ​
 //被代理类
 class Boss implements BuyCoffee{
     @Override
     public void buyCoffee(){
         System.out.println("我想喝咖啡了");
    }
 }
 ​
 //代理类
 class Secretary implements BuyCoffee{
     private BuyCoffee buyCoffee = null;
     
     public Secretary (BuyCoffee buyCoffee){
         this.buyCoffee = buyCoffee;
    }
     
     @Override
     public void buyCoffee(){
         System.out.println("在秘书室等待");
         buyCoffee.buyCoffee();
         System.out.println("买完咖啡送给老板");
    }
 }
 ​
 public class ProxyTest {
     public static void main(String[] args) {
         Boss boss = new Boss();
         boss.buyHosue();
         Secretary secretary = new Secretary(boss);
         secretary.buyHosue();
    }
 }

动态代理就不需要在运行之前就创建代理类,而是在程序运⾏时通过反射的方式来创建具体的代理类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
typescript复制代码 public class DynamicProxyHandler implements InvocationHandler {
 ​
     private Object object;
 ​
     public DynamicProxyHandler(final Object object) {
         this.object = object;
    }
 ​
     @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         System.out.println("在秘书室等待");
         Object result = method.invoke(object, args);
         System.out.println("买完咖啡送给老板");
         return result;
    }
 }
 ​
 public class DynamicProxyTest {
     public static void main(String[] args) {
         Boss boss = new Boss();
         BuyCoffee proxyBuyCoffee = (BuyCoffee) Proxy.newProxyInstance(BuyCoffee.class.getClassLoader(), new
                 Class[]{BuyCoffee.class}, new DynamicProxyHandler(buyHouse));
         proxyBuyHouse.buyHosue();
    }
 }
 ​
 /* 这里的 Proxy.newProxyInstance() 需要传入三个参数
  * ClassLoader loader 指定当前目标对象使用的类加载器
  * Class<?>[] interfaces 指定目标对象实现的接口的类型
  * InvocationHandler 指定动态处理器
  */

动态代理减少了对业务接口的依赖,降低了耦合度。

最后说说动态代理的优缺点,优点是 符合开闭原则,有较好的扩展性,缺点是 当有太多需求时候,需要太多的接口,不利于管理接口;同时接口中的内容一旦发生改变,那么代理类也得进行相应的修改,非常不方便。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%