溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

模板模式(TemplateMethod)和策略(StrategyMethod)模式

發(fā)布時(shí)間:2020-05-04 07:41:31 來源:網(wǎng)絡(luò) 閱讀:456 作者:丘飛飛 欄目:開發(fā)技術(shù)

模板模式和 策略模式使用場(chǎng)景類似,都是把算法進(jìn)行封裝,可以用分離高層算法和低層的具體實(shí)現(xiàn)細(xì)節(jié)。都允許高層算法獨(dú)立于他的具體實(shí)現(xiàn)細(xì)節(jié)的重用。但是實(shí)現(xiàn)方式不同,在實(shí)現(xiàn)方式上,模板模式使用的是繼承,策略模式則使用的委托。

模板模式比較老,缺點(diǎn)是具體的實(shí)現(xiàn)和通用的算法緊密的耦合在了一起,這樣的話具體的一個(gè)實(shí)現(xiàn)只能被一個(gè)算法操縱。父類的的信息更多的暴露給子類。

而策略模式是委托的經(jīng)典用法。策略模式消除了通用的一個(gè)算法和具體實(shí)現(xiàn)的耦合,使得具體的實(shí)現(xiàn)可以被多個(gè)通用的算法操縱。但是策略模式同樣的,增加了類的層次和額外的復(fù)雜性,以內(nèi)存和運(yùn)行時(shí)間開銷作為代價(jià)。

模板模式的UML靜態(tài)圖

模板模式(TemplateMethod)和策略(StrategyMethod)模式

模板模式展示了面向?qū)ο缶幊讨兄T多經(jīng)典重用形式的一種。其中,通用算法被放置在基類中,并且通過繼承在不同的具體上下文中實(shí)現(xiàn)該通用算法。但是這項(xiàng)技術(shù)是有代價(jià)的,繼承是一種非常強(qiáng)的關(guān)系。派生類不可避免的要和他們的基類捆綁在一起。


接下來用一個(gè)示例來演示模板模式的用法:

public abstract class Application {

    protected  abstract void init();
    protected  abstract void idle();
    protected  abstract void cleanup();

    private  boolean isDone = false;
    protected  void setDone(){
        isDone = true;
    }
    protected  boolean done (){
        return  isDone;
    }
    /**
     * 模板模式,把需要執(zhí)行的方法封裝到抽象方法中
     */
    public void  run(){
        init();
        while(!done()){
            idle();;
        }
        cleanup();
    }
}

父類把子類需要實(shí)現(xiàn)的方法作為抽象方法,然后把通用的算法進(jìn)行封裝,封裝到了run方法中

/**
 * Created by wangtf on 2015/11/19.
 * 模板模式
 */
public class FtocTemplateMethod extends Application{

    private InputStreamReader in;
    private BufferedReader br;

    @Override
    protected void init() {
        in = new InputStreamReader(System.in);
        br = new BufferedReader(in);
    }

    public static void main(String[] args) {
        (new FtocTemplateMethod()).run();
    }

    @Override
    protected void idle() {
        String fahrString = readLineAndReturnNullIfError();
        if(fahrString ==null ||fahrString.length()==0){
            setDone();
        }else {
            System.out.println("to do something:" + fahrString);
        }
    }

    @Override
    protected void cleanup() {
        System.out.print("ftoc exit!");
    }

    private  String readLineAndReturnNullIfError(){
        String s ;
        try{
            s = br.readLine();
        }catch (IOException e){
            s = null;
        }
        return s;
    }
}

子類繼承父類,實(shí)現(xiàn)父類中的抽象方法,具體的算法被封裝到了父類中。

策略模式的UML靜態(tài)圖

策略模式使用了一種非常不同的方法類倒置通用算法和具體實(shí)現(xiàn)之間的依賴關(guān)系

模板模式(TemplateMethod)和策略(StrategyMethod)模式

用示例演示策略模式:

/**
 * Created by wangtf on 2015/11/19.
 */
public interface Application {
    public void  init();
    public  void idle();
    public  void cleanUp();
    public  boolean done();
}


定義接口

/**
 * 策略模式
 * Created by wangtf on 2015/11/19.
 */
public class FtosStrategy implements Application{

    private InputStreamReader in;
    private BufferedReader br;
    private  boolean isDone = false;
    @Override
    public void init() {
        in = new InputStreamReader(System.in);
        br = new BufferedReader(in);
    }


    @Override
    public void idle() {
        String fahrString = readLineAndReturnNullIfError();
        if(fahrString ==null ||fahrString.length()==0){
            setDone();
        }else {
            System.out.println("to do something:" + fahrString);
        }
    }

    @Override
    public void cleanUp() {
        System.out.print("ftoc exit!");
    }


    protected  void setDone(){
        isDone = true;
    }
    @Override
    public boolean done() {
        return isDone;
    }

    private  String readLineAndReturnNullIfError(){
        String s ;
        try{
            s = br.readLine();
        }catch (IOException e){
            s = null;
        }
        return s;
    }
}

實(shí)現(xiàn)接口中的內(nèi)容

/**
 * Created by wangtf on 2015/11/19.
 */
public class ApplicationRunner {

    private  Application app ;
    ApplicationRunner(Application app){
        this.app = app;
    }

    public  void run(){
        app.init();
        while(!app.done()){
            app.idle();
        }
        app.cleanUp();
    }
}

ApplicationRunner中封裝算法(Run方法),這樣算法和具體的對(duì)象得以脫離。


實(shí)際上一個(gè)更恰當(dāng)?shù)睦邮且粋€(gè)排序的例子,例如一個(gè)冒泡排序,通常有以下步驟

1、遍歷數(shù)組(排序算法)

2、比較兩個(gè)數(shù)字的大小

3、交換兩個(gè)數(shù)字的位置


這樣如果直接寫的話,比較兩個(gè)數(shù)字大小和交換數(shù)字的位置將會(huì)直接依賴于排序算法,這樣的話我們只能排序數(shù)字,這樣的話就不能把算法脫離開。解決方案是,把2 和3步驟進(jìn)行抽取,算法獨(dú)立,抽取出來以后,我們不光能比較兩個(gè)數(shù)字,同樣的能比較對(duì)象,比較字符串等等一切我們想要排序東西。這樣就可以達(dá)到了算法復(fù)用的效果。


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI