您好,登錄后才能下訂單哦!
模板模式和 策略模式使用場(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)圖
模板模式展示了面向?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)系
用示例演示策略模式:
/** * 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ù)用的效果。
免責(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)容。