[018]Java編程思想——聚合

聚合:類之間的一種引用,表示兩個對象之間是整體和部分的關係,部分的生命週期可以超過整體,如電腦和鼠標;
組合:表示兩個對象之間是整體和部分的關係,部分的生命週期不能超越整體,如人和眼睛。
聚合關係的部分,可以在構造器中通過參數傳遞的形式進行初始化,有時聚合比繼承好用。
下面代碼例子就是很好的解釋:

public interface Moveable {
    void move();
}
import java.util.Random;

public class Tank implements Moveable {

    @Override
    public void move() {
        System.out.println("Tank Moving...");
        try {
            Thread.sleep(new Random().nextInt(10000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

現在我們想在調用move()方法時候,計算一下它的運行時間,一種解決辦法是用繼承,繼承Tank這個類,重寫move()方法。

public class Tank2 extends Tank{
    @override
    public void move(){
        long start = System.currentTimeMillis();
        super.move();
        long end = System.currentTimeMillis();
        System.out.println("time:" + (end-start);
    }
}

當我想在調用move()方法時再調用一段話,又要寫Tank3繼承Tanks2並重寫move()方法,但是我想先調用Tank3的方法,再調用Tank2的方法,則又要重寫,當組合多了的時候,任意組合順序則顯得極爲困難,一個好的解決辦法就是用聚合。

public class TankTimeProxy implements Moveable{

    Moveable target;
    public TankTimeProxy (Moveable target) {
        super();
        this.target = target;
    }

    @Override
    public void move() {
        long start = System.currentTimeMillis();
        System.out.println("starttime:" + start);
        target.move();
        long end = System.currentTimeMillis();
        System.out.println("time:" + (end-start));
    }
}
public class TankLogProxy implements Moveable{

    Moveable target;
    public TankTimeProxy (Moveable target) {
        super();
        this.target = target;
    }

    @Override
    public void move() {
        System.out.println("Tank Start...");
        target.move();
        System.out.println("Tank Stop...");
    }
}

如此便實現了兩種不同的邏輯添加,下面我們來看測試代碼:

public class Client {
    public static void main(String[] args){
        Tank t = new Tank();
        //方式1:先打印時間,再打印日誌
        //TankTimeProxy ttp = new TankTimeProxy (t);
        //TankLogProxy tlp = new TankLogProxy (ttp);
        //方式1:先打印日誌,再打印時間
        TankLogProxy tlp = new TankLogProxy (t);
        TankTimeProxy ttp = new TankTimeProxy (tlp);
        Moveable m = ttp;
        m.move();
    }
}

上面非常巧妙的進行了兩種組合,有再多的限制條件,都可以用這種方法任意組合,程序更加容易維護。這實際是一種靜態代理模式。

發佈了33 篇原創文章 · 獲贊 14 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章