作者 : Stanley 罗昊
写在前面:* 此章内容比较抽象, 所以需要结合实际操作进行讲解 *
* 需要有一定的 java 面向对象基础 *
静态代理的实现步骤(举例说明)
首先, 我们需要建立一个 java 工程来实现一个例子, 从而理解什么是 java 中的静态代理;
建好项目后, 我们需要在项目中新建一个包, 然后在包下建一个接口, 人的接口(Person), 紧接着呢, 我们在接口中创建一个吃饭的方法:
这个方法就被称之为抽象方法, 接下来呢, 我将会去写一个实现类, 它们分别是, 老师 (Teacher) 实现类, 紧接着, 我们需要让这个类实现 Person 这个接口, 并实现 Person 类中定义好的抽象方法:
并且在改方法中输出一句话, 来表示这个方法的所执行的意义;
接下来呢, 我再定义一个学生 (Student) 类, 并全也去实现人类(Person), 并且实现该类中的方法:
以上都创建完毕之后呢, 我们来建立一个测试类, 将 Student 类实例化, 调用学生吃零食这个方法:
打印结果就是 学生在吃零食.....;
同样的, 我们将老师类也在测试类中实例化, 并且调用老师吃饭方法, 那么打印结果就是:
学生在吃零食......
老师在吃饭......
需求增强
完成以上步骤之后呢, 现在我们的需求突然要求增强;
需求变化: 无论是老师还是学生, 我都需要让他们在吃饭之前先跑一圈, 吃饭之后, 再去跑一圈;
我们的需求发生了这样的一个变化, 你该如何实现呢? 下面我列出几个实现的策略:
1. 修改原始代码的实现
这个就很好实现, 比如, 我现在要把学生类根据以上要求增强, 我们只需要去实现类中修改原方法即可:
现在, 我们再运行 Test 这个类看效果:
这种结果, 是不是就是根据以上需求进行增强了;
注: 但是, 这种方式, 非常不提倡使用, 因为, 实际开发中一般不会去修改以及提交的代码,
因为你提交完成之后, 别的小组就会调用你的这行代码, 所以, 在实际开发当中, 我们不会轻易的去修改原始代码;
2. 可以找一个代理
代理主要作用:
来做一些需要增强的事情;
举例: 这个代理, 就类似于, 明星的经纪人.
我们假设现在有一个演员王宝强, 王宝强的经纪人是谁啊 ---------- 宋喆对吧;
王宝强最早出道的时候仅仅是一个小演员, 小演员的时候, 没有经纪人, 所以他只负责跑龙套就行了, 跑龙套对他来说是完全可以应付过来的, 但是随着他越来越火, 他已经不是演戏那么简单了, 他除了演戏, 他还需要拍广告, 还需要宣传, 这些都需要他干对把,
演戏是不是需要他一个人去接戏啊, 接广告的话, 是不是还需要去谈这个广告啊, 如果他只身一人的话, 他还需要去接戏, 接广告, 接宣传, 因为考虑到他经历有限, 是不是这些工作他一个人是无法独自完成的;
这个时候呢, 王宝强就想到了一个办法, 请一个代理, 也就是我们所谓的经纪人;
经纪人干的活就是王宝强可以不亲自去干的活, 而王宝强的核心业务是不是仅仅的去拍戏即可, 一个经纪人可以有经纪多个演员;
代理模式
代理
这个代理, 是不是就类似于上面我所述的经纪人
被代理
被代理, 是不是就是王宝强
静态代理
刚才, 我们用了第一种方式来实现了对需求进行了增强, 很显然, 这样做是不对的, 在实际开发中, 企业里也不允许这样去做, 所以我们把刚才写的那几句打印输出语句给删掉;
那, 接下来就改变一下需求:
学生在吃饭之前, 需要买饭, 吃完饭后需要扔垃圾
从以上需求, 我们大概能分析出来, 吃饭是学生的核心, 然而扔垃圾, 买饭, 是不是就是找一个经纪人就行了;
所以接下来, 我们就给学生找一个代理;
1. 首先, 我们需要建一个类(ProxyStudent)
2. 那么 ProxyStudent 既然是学生的代理类, 那么就必须要有跟学生一样的功能, 另外辅助的功能后续再添加;
刚才学生类实现了一个接口(Person), 那么它的代理类, 也必须要去实现 Person, 吃饭的方法实际上还是学生在做,
这里的核心功能依然是学生自己的, 底层调用的还是学生自己的, 也就是在我的这个代理对象中的吃饭这个方法里面你必须去调用学生的;
既然需要在代理对象中, 需要去调用学生吃饭的方法, 那这个代理对象 (ProxyStudent) 的代理类中, 是不是就需要有学生的属性:
如果直接使用 s., 执行必然是空指针异常, 所以, 我们需要给这个学生对象使用构造器进行初始化;
那么接下来, 我们再需要进行增强, 我们是不是仅需要在 s.chifan(); 方法前后添加就行啦;
这样以来, 是不是就是对原始的方法进行了一次增强;
接下来, 我再写一个测试类(ProxyTest), 进行测试;
那么在测试类中, 我们仅需要调用代理对象即可, 也就是说直接找宋喆, 别再去找王宝强了, 就是这样意思.....
实例化代理对象之后, 我是不是就可以通过代理对象去调用我的吃饭方法啦;
来看下执行结果:
是不是代理帮我买大餐, 我只负责吃饭, 代理帮我扔垃圾;
那么通过这样的一个手段就实现了一个代理;
静态代理分析
那么, 在以上的这个代理类中, 真正的核心方法还是被代理对象的, 你这个吃饭的这个核心方法是不是就是吃零食啊;
学生正在吃零食是不是就是调用学生的, 另外两个是我自己拓展加上去的对吧;
而其他的辅助的方法, 是不是就算是代理去做了;
代理模式的编写要点
1. 和被代理对象实现相同的接口
2. 在代理类中, 需要对被代理对象初始化
3. 需要实现和被 dialing 对象相同的方法, 并且在这个方法中核心 (原始) 业务调用被代理对象的, 增强的业务在这里进行增强就行了
静态代理方式的弊端
静态代理方式是有缺陷的;
1. 如果有很多个对象需要找代理, 那么就需要实现很多个对象的代理类, 这样的话代码臃肿, 用户体验很一般;
2. 如果被代理的方法过多, 每个方法都需要增强, 代码不整洁, 大量搬用的工作
它有这两大缺陷就造成了写大型项目的时候, 就不会用静态代理这个设计模式
来源: https://www.cnblogs.com/StanleyBlogs/p/10761604.html