代理

引題:假如咱們想計算一個方法的運行時間,在不動源代碼的狀況下都是用代理類來代替源碼完成業務。具體方法有下面兩種。java

源碼:dom

 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:繼承方式ide

 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

測試代碼this

 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

總結:從上面的例子咱們能夠看出,使用集成和聚合都可以實現代理。spa

引出問題:繼承和聚合哪一種好呢?實際業務中不光有計算時間,還可能有打印日誌等(會有不少代理)。拿繼承來講,每一種咱們都須要寫一個繼承類。若是混用呢?拿計算時間和日誌來講,先時間後日志。咱們須要先寫時間繼承類,再在時間繼承類的基礎上寫日誌繼承類。若是業務反一下的話,又得重寫這兩個繼承類。這仍是隻有計算時間和打印日誌,若是須要其餘不少種代理呢?這樣顯然這樣很笨重。使用聚合能夠解決這種問題,具體以下:代理

修改計算時間的聚合代理方式,而且添加時間日誌代理,代碼以下:日誌

 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

咱們只須要上面兩個代理類就能夠完成上面所說的全部業務。這是由於代理自己也實現了接口;測試以下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

總結:代理方式選擇了用聚合而不用繼承。blog

引出問題:

相關文章
相關標籤/搜索