第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

模版方法模式

我先問個問題,把大象放冰箱,總共分幾步?你一定脫口而出:三步!第一步把冰箱門打開,第二步把大象放進去,第三部把冰箱門關(guān)上。這道題是不是太簡單了?但當我們考慮細節(jié)的時候就沒這么簡單了。

假如你的冰箱門加了鎖,那么第一步開門時就需要開鎖。第二步把大象放進去也有細節(jié)要考慮。如果你的冰箱是臥式的,那么大象需要躺在里面。如果你的冰箱是立式的,那么大象可以站在里面。像這種主體邏輯一樣,細節(jié)實現(xiàn)不同的場景,我們可以考慮使用模版方法模式。
圖片描述

在軟件建模中,把大象放冰箱是一個算法,我們將其定義為一個模版方法。模版方法用一系列抽象的操作定義一個算法。就像我們例子中的三步,打開冰箱、大象放進去、關(guān)上冰箱門。具體如何開門和關(guān)門,如何放大象進去,則在子類中實現(xiàn)。冰箱不同,采用的方式自然也不同。

模版方法中定義操作的方法和先后步驟。而真正的操作方法實現(xiàn)則在子類中。

1. 實現(xiàn)模版方法

我們看看用代碼如何實現(xiàn)把大象放冰箱。為了便于理解,我們盡量少引入類,我們假設(shè)冰箱自身有個行為是把大象放進來

冰箱抽象類 Fridge

public abstract class Fridge {
    public void placeElephant(){
        System.out.println("開始裝大象");
        openDoor();
        putElephant();
        closeDoor();
        System.out.println("結(jié)束");
    }

    public abstract void openDoor();

    public abstract void putElephant();

    public abstract void closeDoor();
}

Fridge 類中定義了一個模版方法 placeELephan, 里面按照順序調(diào)用 openDoor、putELephant、closeDoor。這三個方法留待子類實現(xiàn)。

下面是兩個具體的冰箱實現(xiàn)類代碼。

立式冰箱類 VerticalFridge

public class VerticalFridge extends Fridge{
    @Override
    public void openDoor() {
        System.out.println("打開立式冰箱門");
    }

    @Override
    public void putElephant() {
        System.out.println("將大象站著放進去");
    }

    @Override
    public void closeDoor() {
        System.out.println("關(guān)上立式冰箱門");
    }
}

臥式冰箱 HorizontalFridge

public class HorizontalFridge extends Fridge{
    @Override
    public void openDoor() {
        System.out.println("打開臥式冰箱門");
    }

    @Override
    public void putElephant() {
        System.out.println("將大象躺著放進去");
    }

    @Override
    public void closeDoor() {
        System.out.println("關(guān)上臥式冰箱門");
    }
}

兩個冰箱子類各自實現(xiàn)三個抽象方法。

客戶端代碼:

public class Client {
    public static void main(String[] args) {
        Fridge fridge;

        fridge = new HorizontalFridge();
        fridge.placeElephant();

        System.out.println("---------I'm a line-----------");

        fridge = new VerticalFridge();
        fridge.placeElephant();
    }
}

客戶端代碼中,兩個不同的子類分表調(diào)用了placeElephant 方法,輸出如下:

開始裝大象
打開臥式冰箱門
將大象躺著放進去
關(guān)上臥式冰箱門
結(jié)束
---------I'm a line-----------
開始裝大象
打開立式冰箱門
將大象站著放進去
關(guān)上立式冰箱門
結(jié)束

兩個子類開始和結(jié)束的步驟一樣,中間步驟的順序也一樣。這些邏輯在父類中實現(xiàn)。每個步驟具體的邏輯則在子類中各自實現(xiàn)。

類圖:
圖片描述

2. 模版方法優(yōu)缺點

2.1 優(yōu)點

分離了算法中變和不變的部分。不變的部分定義在父類的模版方法中。變的部分通過子類實現(xiàn)。不變的算法部分可以被充分復用。當變的部分有新需求時,可以定義新的子類。從而實現(xiàn)了開閉原則。

2.2 缺點

模版意味著死板,我們設(shè)定好模版就必須按照模版的一、二、三步來執(zhí)行。如果我們想調(diào)換順序,或者增加幾步就很難做到。除非定義新的模版?;蛘吆苄⌒牡母膭右延心0?,避免影響現(xiàn)有程序邏輯。但這已經(jīng)違反了開閉原則。

3. 模版方法適用場景

如果我們發(fā)現(xiàn)一系列的算法,主干一樣,只是在局部的實現(xiàn)上有區(qū)別。此時我們可以考慮使用模版方法。把算法主干及不變的部分提煉出來,在父類中實現(xiàn)。抽象出變化部分的方法,交由不同的子類自己去實現(xiàn)。

4.小結(jié)

一般來說我們都是在子類中調(diào)用父類的方法。而模版方法恰恰相反,是父類的方法中調(diào)用子類的實現(xiàn)。正是因為這樣,我們才能把不變的行為抽象到父類中,變化的部分留給子類實現(xiàn)。此外還有一類方法叫做鉤子方法,它不是抽象的方法,父類有其缺省實現(xiàn),一般是空方法。但是子類也可以通過重寫去覆蓋。