設計模式之模板方法模式(三)

模板方法模式是一個很常見的模式,可是也須要咱們擁有一雙銳利的眼睛,由於模板方法有許多實現,而他們看起來並不必定和書上所講的設計一致。java

這個模式很常見是由於對建立框架來講,這個模式簡直棒極了。由框架控制如何作事情,而由你(使用這個框架的人)指定框架算法中每一個步驟的細節。算法

用模板方法排序

咱們常常須要數組作什麼事情?對了!排序。編程

Java數組類的設計者提供給咱們一個方便的模板方法用來排序。讓咱們看看這個方法如何運行:設計模式

這裏有兩個方法,共同提供排序的功能,這裏提供了Java的部分源碼數組

public static void sort(Object[] a) {
    Object aux[] = (Object[])a.clone();
    mergeSort(aux, a, 0, a.length, 0);
}

private static void mergeSort(Object[] src, Object[] dest,int low,int high, int off) {
    // 這裏省略其餘實現
    int length = high - low;
    if (length < INSERTIONSORT_THRESHOLD) {
        for (int i=low; i<high; i++)
            for (int j=i; j>low &&
                     ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
                swap(dest, j, j-1);
        return;
    }
    // 這裏省略其餘實現
}

排序鴨子

加入咱們有一個鴨子的數組須要排序,你要怎麼作?數組的排序模板方法已經提供了算法,可是你必須讓這個模板方法知道如何比較鴨子。你要作的事情就是,實現一個compareTo()方法。框架

事情是這樣的:sort()的設計者但願這個方法能使用於全部的數組,因此他們把sort變成是靜態方法,這樣一來,任何數組均可以使用這個方法。可是不要緊,它使用起來和它被定義在超類是同樣的。如今,還有一個細節要告訴你:由於sort並非真正定義在超類中,因此sort方法須要知道你已經實現了這個compareTo方法,不然就沒法進行排序。工具

要達到這一點,設計者利用了Comparable接口。你須實現這個接口,提供這個接口所聲明的方法,也就是compareTo()。學習

public class Duck implements Comparable<Duck> {
    String name;
    int weight;
  
    public Duck(String name, int weight) {
        this.name = name;
        this.weight = weight;
    }
 
    public String toString() {
        return name + " weighs " + weight;
    }
  
    public int compareTo(Duck object) {
 
        Duck otherDuck = object;
  
        if (this.weight < otherDuck.weight) {
            return -1;
        } else if (this.weight == otherDuck.weight) {
            return 0;
        } else { // this.weight > otherDuck.weight
            return 1;
        }
    }
}

讓咱們來測試下這個程序測試

public class DuckSortTestDrive {

    public static void main(String[] args) {
        Duck[] ducks = { 
                        new Duck("Daffy", 8), 
                        new Duck("Dewey", 2),
                        new Duck("Howard", 7),
                        new Duck("Louie", 2),
                        new Duck("Donald", 10), 
                        new Duck("Huey", 2)
         };

        System.out.println("Before sorting:");
        display(ducks);

        Arrays.sort(ducks);
 
        System.out.println("\nAfter sorting:");
        display(ducks);
    }

    public static void display(Duck[] ducks) {
        for (Duck d : ducks) {
            System.out.println(d);
        }
    }
}

觀察鴨子排序的內部工做

讓咱們追蹤Array類的sort模板方法的工做過程。咱們會看到模板方法是如何控制算法的,以及在算法中的某些點上它是如何要求咱們的鴨子提供某個步驟的實現的ui

  1. 首先咱們須要鴨子數組
  2. 而後調用Array類的sort模板方法,並傳入鴨子數組
  3. 想要排序一個數組,你須要一次又一次地比較兩個項目,直到整個數組都排序完畢
  4. 若是鴨子的次序不對,就用Array的具體swap方法將二者對調
  5. 排序方法會持續比較並對調鴨子,直到整個數組次序是正確的

是否是很驚訝,這個也是模板方法的一種實現呢。雖然不是教科書上的模板方法,但它的實現仍然符合模板方法模式的精神。在Java的API中,還能夠看到其餘的。好比java.io的InputStream類有一個read()方法,是由子類實現的,而這個方法又會被read(byte b[],int off,int len)模板方法使用。

還有模板方法和策略模式都是封裝組合,一個用組合,一個用繼承,你搞明白了嗎?若是仍是太籠統的話,那麼,小編請你仔細翻書《Head First設計模式》看一下這章吧,而後咱們再討論。

設計箱內的工具

總結時間到了

  • OO基礎

    抽象、封裝、繼承、多態

  • OO原則

    封裝變化

    多用組合,少用繼承

    針對接口編程,不針對實現編程

    爲交互對象之間的鬆耦合設計而努力

    依賴抽象,不要依賴具體類

    類應該對擴展開放,對修改關閉

    只和朋友交談

    別找我,我會找你(咱們最新的原則提醒你,由超類主控一切,當它們須要的時候,天然會去調用子類,這就跟好萊塢同樣

    只和朋友交談

  • OO模式

    『策略模式』、『觀察者模式』、『裝飾者模式』、『抽象工廠模式』、『工廠方法模式』、『單例模式』、『命令模式』、『適配器模式』、『外觀模式』

    模板方法模式』在一個方法中定義一個算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類能夠在不改變算法結構的狀況下,從新定義算法中的某些步驟。

學習完模板方法模式,小編才知道,原來在平時頻繁使用的設計模式中,他也佔據着一個重要的地位,學習以前,小編是全然不知呀。此次終於get到這個模式,而且儲備了知識,還須要慢慢消化噢。

下次,咱們一塊兒走進迭代器和組合模式的世界。

愛生活,愛學習,愛感悟,愛挨踢

相關文章
相關標籤/搜索