iT邦幫忙

2023 iThome 鐵人賽

0
自我挑戰組

深入淺出設計模式 (Head First Design Pattern) - 重點整理及範例分享系列 第 33

[深入淺出設計模式] Ch8 The Template Method Pattern (2) - 模板模式 範例 動物排序

  • 分享至 

  • xImage
  •  

上篇解釋完模板模式
手癢還是把書中另一個排序的範例寫了一下哈哈
假設今天有不同的動物類別
共同點是他們都有某種數值可以排序
我們就可以繼續用模板模式啦~

首先定義了一個名為 Comparable 的介面。這個介面定義了兩個重要的方法:compare() 與displayVal()。這樣做的目的是為了讓不同類型的物件能夠實現自己的比較邏輯和顯示方式。

template<class T>
class Comparable {
public:
    virtual bool compareTo(T other) = 0;
    virtual void displayVal() = 0;
};

接著我們定義了兩個類別,分別是Duck與Chicken。這兩個類別都繼承了Comparable介面,並實現了比較方法和顯示值方法。這樣一來,不同類型的鳥類都可以進行比較和顯示值的操作。

class Duck : public Comparable<Duck> {
public:
    string name;
    int weight;
public:
    Duck(string name, int val);
    bool compareTo(Duck other) override;
    void displayVal() override;
};
Duck::Duck(string name, int val){
    this -> name = name;
    this -> weight = val;
}
bool Duck::compareTo(Duck other){
    return (this -> weight <= other.weight);
}
void Duck::displayVal(){
    cout << weight;
}

另外也定義了一個名為 Sort 的類別,這個類別是一個模板類別,可以與任何實現了Comparable介面的類別一起使用。這個類別包含了合併排序的方法以及顯示陣列值的方法。

template<class T>
class Sort{
    public: 
        T *ary;
        int size;
    public:        
        void showAry();
        void setAry(T *ary, int size);
        void merge(int l, int r);
        void mergeSort(int l, int r);
};

template<class T> void Sort<T>::setAry(T *ary, int size){
    this -> size = size;
    this -> ary = ary;
}

template<class T> void Sort<T>::showAry(){
    for(int i = 0; i < size; i++){
        cout << ary[i].name << ": ";
        ary[i].displayVal();
        if(i != size - 1){
            cout << ", ";
        }
    }
    cout << endl;
}

template<class T> void Sort<T>::merge(int l, int r) {
    int m = (l + r) / 2;
    int i = l;
    int j = m + 1;
    while (i <= m && j <= r) {
        //ary[i] <= ary[j]
        if (ary[i].compareTo(ary[j])){
            i++;
        } else {
            T key = ary[j];
            for (int k = j; k > i; k--) {
                ary[k] = ary[k - 1];
            }
            ary[i] = key;
            j++;
            m++;
        }
    }
}

template<class T>void Sort<T>::mergeSort(int l, int r){
    int m = (r + l) / 2;
    if(m > l){
        mergeSort(l, m);
        mergeSort(m + 1, r);
    }    
    merge(l, r);
}

這個模式使得我們可以輕鬆地擴展和修改程式,去兼容未來可能出現的不同類型的動物,同時也提高了程式的可讀性和可維護性。

最後是main跟輸出:

int main(){
    Duck a("Alice", 24);
    Duck b("Bob", 29);
    Duck c("Tray", 14);
    Duck d("Louis", 37);

    Duck duckAry[] = {a, b, c, d};
    int size = sizeof(duckAry) / sizeof(Duck);
    Sort<Duck> algo;
    algo.setAry(duckAry, size);
    algo.mergeSort(0, size - 1);
    algo.showAry();

    Chicken e(0, "Elisa", 54);
    Chicken f(1, "Felix", 41);
    Chicken g(0, "Gaby", 94);
    Chicken h(1, "Harry", 62);
    Chicken i(0, "Iris", 49);
    Chicken chickenAry[] = {e, f, g, h, i};
    int chickenSize = sizeof(chickenAry) / sizeof(Chicken);
    Sort<Chicken> chickSort;
    chickSort.setAry(chickenAry, chickenSize);
    chickSort.mergeSort(0, chickenSize - 1);
    chickSort.showAry();
}

輸出:
Tray: 14, Alice: 24, Bob: 29, Louis: 37
Felix: 41, Iris: 49, Elisa: 54, Harry: 62, Gaby: 94


參考資料:

  1. 《深入淺出設計模式 (Head First Design Patterns) 》
  2. 書中官方程式碼傳送門
  3. 本篇程式碼傳送門

Disclaimer
因為讀的是原文版,所以難免會有翻譯詞不達意或是專有名詞上的差異,有錯誤的話歡迎在留言區一起交流!


上一篇
[深入淺出設計模式] Ch8 The Template Method Pattern (1) - 模板模式 範例 製作飲料
下一篇
[深入淺出設計模式] Ch9 The iterator and composite patterns (1) - 迭代器模式和組合模式
系列文
深入淺出設計模式 (Head First Design Pattern) - 重點整理及範例分享35
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言