1. 程式人生 > >設計模式(22)-----代理設計模式-----靜態代理

設計模式(22)-----代理設計模式-----靜態代理

一:用繼承實現靜態代理

 

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