設計模式(22)-----代理設計模式-----靜態代理
阿新 • • 發佈:2018-11-01
一:用繼承實現靜態代理
1 package com.DesignPatterns.al.Dynamic1; 2 3 public interface Moveable { 4 public void move(); 5 }
package com.DesignPatterns.al.Dynamic1; import java.util.Random; public class Tank implements Moveable { @Override public void move() { System.out.println("坦克在移動"); try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.DesignPatterns.al.Dynamic1; /** * 用繼承計算tank中move的執行時間 * * @author qingruihappy * @data 2018年10月31日 下午11:19:43 * @說明:*/ public class Tank1 extends Tank { @Override public void move() { long startTime = System.currentTimeMillis(); super.move(); long endTime = System.currentTimeMillis(); System.out.println("tank總共花費時間是" + (endTime - startTime)); } }
1 package com.DesignPatterns.al.Dynamic1;2 /** 3 * 用繼承實現靜態代理 4 * @author qingruihappy 5 * @data 2018年11月1日 上午1:05:36 6 * @說明: 7 */ 8 public class Test { 9 public static void main(String[] args) { 10 Moveable m=new Tank1(); 11 m.move(); 12 } 13 14 }
二,用聚合實現靜態代理
package com.DesignPatterns.al.Dynamic2; public interface Moveable { public void move(); }
package com.DesignPatterns.al.Dynamic2; import java.util.Random; public class Tank implements Moveable { @Override public void move() { System.out.println("坦克在移動"); try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.DesignPatterns.al.Dynamic2; /** * 聚合實現: 聚合:在一個類中有另一個類的實現,站在代理的角度來說就是當前類是代理類,裡面的另一個類就是目標類,呼叫代理類的時候就是呼叫目標類的方法。 * Tank2中有Tank的類,操作的就是Tank相關的方法。 * * @author qingruihappy * @data 2018年10月31日 下午11:26:45 * @說明: */ public class Tank2 implements Moveable { Tank t; public Tank2(Tank t) { super(); this.t = t; } @Override public void move() { long startTime = System.currentTimeMillis(); t.move(); long endTime = System.currentTimeMillis(); System.out.println("tank總共花費時間是" + (endTime - startTime)); } }
package com.DesignPatterns.al.Dynamic2; public class Test { public static void main(String[] args) { Moveable m=new Tank2(new Tank()); m.move(); } }
三,繼承和聚合的對比
package com.DesignPatterns.al.Dynamic3; public interface Moveable { public void move(); }
package com.DesignPatterns.al.Dynamic3; import java.util.Random; public class Tank implements Moveable { @Override public void move() { System.out.println("坦克在移動"); try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.DesignPatterns.al.Dynamic3; /** * 現在我們來說一下為什麼用實現(聚合),不用繼承。 * 最概要的說法就是實現解耦,因為設計模式的要義是面向抽象程式設計而不是實現程式設計 * 設計模式還有一個要義就是:少用繼承,多用組合。 * 下面我們舉例來說明。 * * @author qingruihappy * @data 2018年10月31日 下午11:26:45 * @說明: */ public class TankLog implements Moveable { Moveable t; public TankLog(Moveable t) { super(); this.t = t; } @Override public void move() { System.out.println("tank開始列印日誌"); t.move(); System.out.println("tank開始列印結束"); } }
package com.DesignPatterns.al.Dynamic3; /** * 現在我們來說一下為什麼用實現(聚合),不用繼承。 * 最概要的說法就是實現解耦,因為設計模式的要義是面向抽象程式設計而不是實現程式設計 * 設計模式還有一個要義就是:少用繼承,多用組合。 * 下面我們舉例來說明。 * * @author qingruihappy * @data 2018年10月31日 下午11:26:45 * @說明: */ public class TankTime implements Moveable { Moveable t; public TankTime(Moveable t) { super(); this.t = t; } @Override public void move() { System.out.println("tank開始列印開始時間"); long startTime = System.currentTimeMillis(); t.move(); long endTime = System.currentTimeMillis(); System.out.println("tank開始列印結束時間"); System.out.println("tank總共花費時間是" + (endTime - startTime)); } }
package com.DesignPatterns.al.Dynamic3; /** * 現在假如我們有一個列印日誌的代理,一個列印時間的代理(甚至還有事物的代理,還比如說我檢查當前的人有沒有執行我這個方法的許可權等等)。 * 假如我們用繼承的話會怎麼辦呢,我們就的讓列印日誌的代理繼承目標,再讓列印時間的代理繼承時間的類,讓事物的代理繼承代理時間的類,讓執行許可權的代理繼承事物的代理...... *。還有就是假如現在我們換了順序了,先出列印日誌的代理,然後在用時間的代理繼承時間的代理,那麼又會多出來兩個代理類,想想都是一件恐怖的事情,類太多了。 * * 但是我們用介面(聚合呢,我們來看這個例子。) * 聚合有點類似於裝飾著設計模式:在這裡我們要注意這幾模式其實更看重的是使用場景,而不是具體細節的用法。 * 其實設計模式多多少少都想多型,但是我們注意設計模式更看重的是語義上的而不是語法上的。 * * * 現在靜態的代理已經將完了,但是我們來看這個代理有什麼缺陷,首先代理類和目標類必須繼承相同的介面(雖然是缺點但是可以接受) * 但是還有一個就是,假如現在有其它的類加car也需要實現列印時間的代理,那我們怎麼做的,你說好說,在寫一個car的代理唄。 * 那假如現在有自行車,火車,貨車,電瓶車,小推車,等等100多個都要求實現時間的代理,是不是需要些100多個類呢。 * * 下面就引出了動態代理。 * @author qingruihappy * @data 2018年11月1日 上午12:39:35 * @說明: */ public class Test { public static void main(String[] args) { /* TankTime m=new TankTime(new Tank()); TankLog n=new TankLog(m); n.move();*/ TankLog m=new TankLog(new Tank()); TankTime n=new TankTime(m); n.move(); } }
tank開始列印日誌
tank開始列印開始時間
坦克在移動
tank開始列印結束時間
tank總共花費時間是636
tank開始列印結束
tank開始列印開始時間
tank開始列印日誌
坦克在移動
tank開始列印結束
tank開始列印結束時間
tank總共花費時間是270