代理
分类:
IT文章
•
2024-10-14 12:21:42
引题:假如我们想计算一个方法的运行时间,在不动源代码的情况下都是用代理类来代替源码完成业务。具体方法有下面两种。
源码:
1 package com.liuzhihong.inter;
2 /**
3 * @ClassName Moveable
4 * @Description
5 * @Author 刘志红
6 * @Date 2019/4/3
7 **/
8 public interface Moveable {
9 void move();
10 }
View Code
1 package com.liuzhihong.waitproxy;
2 import com.liuzhihong.inter.Moveable;
3 /**
4 * @ClassName Person
5 * @Description
6 * @Author 刘志红
7 * @Date 2019/4/3
8 **/
9 public class Person implements Moveable {
10 @Override
11 public void move() {
12 System.out.println("Person.move");
13 try {
14 Thread.sleep((int) (Math.random() * 10000));
15 } catch (InterruptedException e) {
16 e.printStackTrace();
17 }
18 }
19 }
View Code
1:继承方式
1 package com.liuzhihong.ext;
2 import com.liuzhihong.waitproxy.Person;
3
4 import java.time.Duration;
5 import java.time.Instant;
6 /**
7 * @ClassName PersonExtend
8 * @Description
9 * @Author 刘志红
10 * @Date 2019/4/3
11 **/
12 public class PersonExtend extends Person {
13 @Override
14 public void move() {
15 Instant start = Instant.now();
16 super.move();
17 Instant end = Instant.now();
18 System.out.println("运行时间"+ Duration.between(start,end).toMillis());
19 }
20 }
View Code
2:聚合方式
1 package com.liuzhihong.polymerization;
2 import com.liuzhihong.inter.Moveable;
3 import com.liuzhihong.waitproxy.Person;
4
5 import java.time.Duration;
6 import java.time.Instant;
7 /**
8 * @ClassName PersonPol
9 * @Description
10 * @Author 刘志红
11 * @Date 2019/4/3
12 **/
13 public class PersonPol implements Moveable {
14 private Person person;
15 public PersonPol(Person person) {
16 this.person = person;
17 }
18 @Override
19 public void move() {
20 Instant start = Instant.now();
21 person.move();
22 Instant end = Instant.now();
23 System.out.println("Program RunningTime:"+ Duration.between(start, end).toMillis());
24 }
25 }
View Code
测试代码
1 package com.liuzhihong.test;
2 import com.liuzhihong.ext.PersonExtend;
3 import com.liuzhihong.polymerization.PersonPol;
4 import com.liuzhihong.waitproxy.Person;
5 import org.junit.Test;
6 /**
7 * @ClassName Test
8 * @Description
9 * @Author 刘志红
10 * @Date 2019/4/3
11 **/
12 public class TestProxy {
13 @Test
14 public void testEXC(){
15 new PersonExtend().move();
16 }
17
18 @Test
19 public void testPlo(){
20 new PersonPol(new Person()).move();
21 }
22 }
View Code
总结:从上面的例子我们可以看出,使用集成和聚合都能够实现代理。
引出问题:继承和聚合哪种好呢?实际业务中不光有计算时间,还可能有打印日志等(会有很多代理)。拿继承来说,每一种我们都需要写一个继承类。如果混用呢?拿计算时间和日志来说,先时间后日志。我们需要先写时间继承类,再在时间继承类的基础上写日志继承类。如果业务反一下的话,又得重写这两个继承类。这还是只有计算时间和打印日志,如果需要其他很多种代理呢?这样显然这样很笨重。使用聚合可以解决这种问题,具体如下:
修改计算时间的聚合代理方式,并且添加时间日志代理,代码如下:
1 package com.liuzhihong.polymerization;
2 import com.liuzhihong.inter.Moveable;
3 import com.liuzhihong.waitproxy.Person;
4
5 import java.time.Duration;
6 import java.time.Instant;
7 /**
8 * @ClassName PersonPol
9 * @Description
10 * @Author 刘志红
11 * @Date 2019/4/3
12 **/
13 public class TimeProxy implements Moveable {
14 private Moveable moveable;
15 public TimeProxy(Moveable moveable) {
16 this.moveable = moveable;
17 }
18 @Override
19 public void move() {
20 Instant start = Instant.now();
21 moveable.move();
22 Instant end = Instant.now();
23 System.out.println("Program RunningTime:" + Duration.between(start, end).toMillis());
24 }
25 }
View Code
1 package com.liuzhihong.polymerization;
2 import com.liuzhihong.inter.Moveable;
3 /**
4 * @ClassName LogProxy
5 * @Description
6 * @Author 刘志红
7 * @Date 2019/4/3
8 **/
9 public class LogProxy implements Moveable {
10 private Moveable moveable;
11 public LogProxy(Moveable moveable) {
12 this.moveable = moveable;
13 }
14 @Override
15 public void move() {
16 System.out.println("method begin...");
17 moveable.move();
18 System.out.println("method end!!!");
19 }
20 }
View Code
我们只需要上面两个代理类就可以完成上面所说的所有业务。这是因为代理本身也实现了接口;测试如下
1 package com.liuzhihong.test;
2 import com.liuzhihong.polymerization.LogProxy;
3 import com.liuzhihong.polymerization.TimeProxy;
4 import com.liuzhihong.waitproxy.Person;
5 import org.junit.Test;
6 /**
7 * @ClassName Test
8 * @Description
9 * @Author 刘志红
10 * @Date 2019/4/3
11 **/
12 public class TestProxy {
13 /**
14 * 计算时间
15 */
16 @Test
17 public void testTime() {
18 new TimeProxy(new Person()).move();
19 }
20 /**
21 * 加日志
22 */
23 @Test
24 public void testLog() {
25 new LogProxy(new Person()).move();
26 }
27 /**
28 * 日志包计算时间
29 */
30 @Test
31 public void testTimeLog() {
32 new LogProxy(new TimeProxy(new Person())).move();
33 }
34 /**
35 * 计算时间包日志
36 */
37 @Test
38 public void testLogTime() {
39 new TimeProxy(new LogProxy(new Person())).move();
40 }
41 }
View Code
总结:代理方式选择了用聚合而不用继承。
引出问题: