<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    合工大很牛很牛牛

      BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
      14 Posts :: 1 Stories :: 37 Comments :: 0 Trackbacks

     

    茶和咖啡是兩個功能類似的類:咖啡的制作包括boil water, brew, pour, add condiments四步,而沏茶的過程包括boil water, steep, pour, add lemon四步。

    它們的一,三兩步相同,二,四兩步類似,如下:

    class Coffee {

        public void boilWater() {

            System.out.println("Boiling water");

        }

        public void brew() {

            System.out.println("Brewing Coffee in the water");

        }

        public void pour() {

            System.out.println("Pour Coffee in cup");

        }

        public void addCondiments() {

            System.out.println("Add sugar and Milk in the coffee");

        }

    }

    class Tea {

        public void boilWater() {

            System.out.println("Boiling water");

        }

        public void steep() {

            System.out.println("Steep te                                                                                                                                         a in the water");

        }

        public void pour() {

            System.out.println("Pour tea in cup");

        }              

        public void addLemon() {

            System.out.println("Add lemon in the tea");

        }

    }

    為了減少重復(fù),增加復(fù)用,我們給它們加一個共同的抽象父類:CaffeineBeverage

    兩個子類中相同的部分移到了父類中,變成父類的方法;不同的部分在父類中寫成抽象方法,具體實現(xiàn)放到子類中(對比工廠方法,工廠方法是把對象的創(chuàng)建方法放到了子類中)。

    另外,添加了一個prepareRecipe方法,相當(dāng)于“一鍵”功能(這個和façade pattern的一鍵功能是有區(qū)別的,這里“一鍵”是寫在抽象父類中,而在façade pattern里,是寫在客戶端和類庫之間的一個新增的類中)。如下:

    package javaapplication36;

    public class Main {

        public static void main(String[] args) {

            CaffeineBeverage beverage = new Coffee();

            beverage.prepareRecipe();

            beverage = new Tea();

            beverage.prepareRecipe();

        }

    }

    abstract class CaffeineBeverage {

        public void prepareRecipe() {

            boilWater();

            brew();

            pour();

            addCondiments();

        }

        public void boilWater() {

            System.out.println("Boiling water");

        }

        public abstract void brew();

        public void pour() {

            System.out.println("Pour into the cup");

        }

        public abstract void addCondiments();

    }

    class Coffee extends CaffeineBeverage {

        public void brew() {

            System.out.println("Brewing Coffee in the water");

        }

        public void addCondiments() {

            System.out.println("Add sugar and Milk in the coffee");

        }

    }

    class Tea extends CaffeineBeverage {

        public void brew() {

            System.out.println("Steep the tea");

        }

        public void addCondiments() {

            System.out.println("Add lemon in the tea");

        }

    }

    在以上代碼中:父類的prepareRecipe方法實際上就是所謂的Template 方法,template方法中所調(diào)用的其他函數(shù),有的在父類中已經(jīng)實現(xiàn),有的會根據(jù)不同的子類,而采用不同的實現(xiàn)。

    Template pattern:即算法(prepareRecipe方法)在父類中寫好了,會調(diào)用父類里的各種方法來實現(xiàn)(boilingwaterbrewpouraddCondiments),這些方法有的會在父類中就已經(jīng)實現(xiàn),有的會放到子類中實現(xiàn)之。

    再把程序?qū)懙母晟菩河捎谒惴?/span>prepareRecipe是不會變動的,所以我們給它加上final,而對于addCondiments ,有的飲料有可能需要配料,而有的飲料根本不可能添加配料。(也就是說有的子類, prepareRecipe方法中需要執(zhí)行addCondiments功能,而有的子類不需要。)

    為了不寫幾種重復(fù)prepareRecipe方法(prepareRecipe1, prepareRecipe2….每種方法只是有個別步驟不一樣),我們使用Hook方式來做(Hook就是指一個包含空內(nèi)容的實體方法,不同于抽象方法),如下:

    package javaapplication36;

    public class Main {

        public static void main(String[] args) {

            CaffeineBeverage beverage = new Coffee();

            beverage.prepareRecipe();

            beverage = new Tea();

            beverage.prepareRecipe();

            beverage = new Milk();

            beverage.prepareRecipe();

        }

    }

    abstract class CaffeineBeverage {

        public void prepareRecipe() {

            boilWater();

            brew();

            pour();

            addCondiments();

        }

        public void boilWater() {

            System.out.println("Boiling water");

        }

        public abstract void brew();

        public void pour() {

            System.out.println("Pour into the cup");

        }

        public void addCondiments() { //HOOK,一個空方法,不做任何事情,繼承的子類根據(jù)需//要覆蓋或者保持它為空。

        }

    }

    class Coffee extends CaffeineBeverage {

        public void brew() {

            System.out.println("Brewing Coffee in the water");

        }

        public void addCondiments() { //addCondiments重寫

            System.out.println("Add sugar and Milk in the coffee");

        }

    }

    class Tea extends CaffeineBeverage {

        public void brew() {

            System.out.println("Steep the tea");

        }

        public void addCondiments() { //addCondiments重寫

            System.out.println("Add lemon in the tea");

        }

    }

    class Milk extends CaffeineBeverage { //沒有對addCondiments重寫

        public void brew() {

            System.out.println("Brewing Milk in the water.");

        }

    }

    最后,我們試圖更進(jìn)一步完善代碼,即使子類有addCondiments這個方法,我們也可以根據(jù)客戶端的需要,選擇在執(zhí)行prepareRecipe的時候是否進(jìn)行addCondiments這一步。

    package javaapplication36;

    import java.io.BufferedReader;

    import java.io.IOException;

    import java.io.InputStreamReader;

    import java.util.logging.Level;

    import java.util.logging.Logger;

    public class Main {

        public static void main(String[] args) {

            CaffeineBeverage beverage = new Coffee();

            beverage.prepareRecipe();

            beverage = new Tea();

            beverage.prepareRecipe();

            beverage = new Milk();

            beverage.prepareRecipe();

        }

    }

    abstract class CaffeineBeverage {

        public void prepareRecipe() {

            boilWater();

            brew();

            pour();

            if (customerWantCondiments()) {

                addCondiments();

            }

        }

        public void boilWater() {

            System.out.println("Boiling water");

        }

        public abstract void brew();

        public void pour() {

            System.out.println("Pour into the cup");

        }

        public void addCondiments() {

        }

        public boolean customerWantCondiments() {

            return true;//相當(dāng)于不做任何判斷就直接讓prepareRecipe執(zhí)行addCondiments()

        }

    }

    class Coffee extends CaffeineBeverage {

        public void brew() {

            System.out.println("Brewing Coffee in the water");

        }

        @Override

        public void addCondiments() {

            System.out.println("Add sugar and Milk in the coffee");

        }

        @Override

        public boolean customerWantCondiments() {

            String answer = getUserInput();

            if (answer.startsWith("y")) {

                return true;

            }

            else {

                return false;

            }

        }

        private String getUserInput() { //獲取輸入,確定是否要Condiments

            System.out.println("Would you love some condiments? (y/n)");

            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

            String answer = null;

            try {

                answer = in.readLine();

            }

            catch (IOException ex) {

                Logger.getLogger(Coffee.class.getName()).log(Level.SEVERE, null, ex);

            }

            answer = answer.toLowerCase();

            return answer;

        }

    }

    class Tea extends CaffeineBeverage {

        public void brew() {

            System.out.println("Steep the tea");

        }

        @Override

        public void addCondiments() {

            System.out.println("Add lemon in the tea");

        }

    }

    class Milk extends CaffeineBeverage {

        public void brew() {

            System.out.println("Brewing Milk in the water.");

        }

    }

    再舉一例,很常見的,自定義類型數(shù)組的比較就是用到了Template pattern,如下:

    package javaapplication37;

    import java.util.Arrays;

    public class Main {

        public static void main(String[] args) {

            Duck[] ducks = {new Duck("duck1", 10), new Duck("duck2", 13), new Duck("duck3", 9)};

            displayDucks(ducks);

            Arrays.sort(ducks);//Arrays相當(dāng)于template pattern中的抽象父類,sort是該類中的//算法函數(shù)

            displayDucks(ducks);

        }

        private static void displayDucks(Duck[] ducks) {

            for (int i = 0; i < ducks.length; i++) {

                System.out.println(ducks[i].toString());

            }

        }

    }

    class Duck implements Comparable {

        String name;

        int weight;

        Duck(String name, int weight) {

            this.name = name;

            this.weight = weight;

        }

        @Override

        public String toString() {

            return name + ":" + weight;

        }

        public int compareTo(Object o) { //compareTo方法相當(dāng)于HOOK

            Duck otherDuck = (Duck) o;

            if (this.weight < otherDuck.weight) {

                return -1;

            }

            else if (this.weight == otherDuck.weight) {

                return 0;

            }

            else {

                return 1;

            }

        }

    }

    我們來看看Arrays這個類是如何使用template pattern的。

    public class Arrays {

    public static void sort(Object[] a) { //sort是算法函數(shù)

            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;

             // Insertion sort on smallest arrays

            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;

            }

    }

    }

    public interface Comparable<T> {

        public int compareTo(T o); //compareToHOOK

    }

    再舉一例,看看Swing中的JFrame是如何使用template pattern的:

    package javaapplication38;

    import java.awt.Graphics;

    import javax.swing.JFrame;

    public class Main {

        public static void main(String[] args) {

            MyFrame frame = new MyFrame("my first frame");

        }

    }

    class MyFrame extends JFrame { //JFrame 相當(dāng)于template pattern中的父類,而它里面的//update方法就是其算法函數(shù)

        public MyFrame(String title) {

            super(title);

            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            this.setSize(300, 300);

            this.setVisible(true);

        }

        public void paint(Graphics g) { //paintHOOK

            super.paint(g);

            String msg = "i rule";

            g.drawString(msg, 100, 50);

        }

    }

    posted on 2008-07-09 15:38 化的了 閱讀(1582) 評論(3)  編輯  收藏 所屬分類: 設(shè)計模式

    Feedback

    # re: template pattern 2008-07-09 17:21 深圳朋悅速8酒店梅林店
    http://www.tkk7.com  回復(fù)  更多評論
      

    # re: template pattern 2008-07-09 19:20 leekiang
    貌似抽象類實現(xiàn)幾個方法,留幾個接口,實現(xiàn)的方法要調(diào)接口,這就是模板了。  回復(fù)  更多評論
      

    # re: template pattern 2008-07-09 22:23 化的了
    @leekiang
    其實模板的目的就是保持算法的穩(wěn)定,然后就搞了一大堆類似工廠方法的東西。。。  回復(fù)  更多評論
      

    主站蜘蛛池模板: 亚洲片国产一区一级在线观看| 天天看免费高清影视| 国产亚洲日韩在线三区| 美女被爆羞羞网站免费| 日韩亚洲国产二区| 日韩免费在线中文字幕| 亚洲女人被黑人巨大进入| 一区二区三区免费高清视频| 亚洲精品色婷婷在线影院| a级毛片免费观看网站| 亚洲国产天堂久久综合| 久久久久久久国产免费看| 亚洲精品无码久久一线| 亚洲a一级免费视频| 亚洲色偷偷偷网站色偷一区| 午夜性色一区二区三区免费不卡视频| 亚洲天堂一区在线| 在线免费观看一级片| 黄色a三级三级三级免费看| 亚洲精品无码久久久久| 免费无码VA一区二区三区| 亚洲w码欧洲s码免费| 精品国产精品久久一区免费式| 男人和女人高潮免费网站| 国产亚洲一区二区三区在线不卡| 日韩电影免费在线观看网站| 亚洲国产精品一区二区久久| 毛片免费全部播放一级| 国产AV无码专区亚洲AV琪琪| 中文字幕亚洲无线码| 91精品成人免费国产片| 午夜亚洲国产理论片二级港台二级| 亚洲人成色77777在线观看大| 青青草无码免费一二三区| 亚洲精品久久无码av片俺去也| AV在线播放日韩亚洲欧| 1000部拍拍拍18勿入免费视频下载| 亚洲精品美女久久久久久久| 中文字幕亚洲乱码熟女一区二区| 国产免费一区二区三区| 日韩在线观看视频免费|