模版方法模式屬於行爲型模式。java
該模式定義一個操做中算法的框架,而將一些步驟延遲到了子類中,使得子類能夠不改變算法的結構便可從新定義算法中的某些特定步驟。算法
模版方法模式是編程中常常會用到的一種模式。編程
模版方法模式由一個抽象類和一個實現類經過繼承的結構組成,抽象類中的方法分爲三種框架
抽象方法:父類中只聲明但不加以實現,而是定義好規範,而後由他的子類去實現。ide
模版方法:由抽象類聲明並加以實現,但通常來講,模版方法中會調用抽象方法來完成主要的邏輯功能,而且,模版方法大多會定義爲final類型,指明主要的邏輯功能在子類中不能被重寫。測試
鉤子方法:由抽象類聲明並加以實現。可是子類能夠去擴展,子類能夠經過擴展鉤子方法來影響模版方法的邏輯。spa
抽象類的任務是搭建邏輯框架,實現類用於實現細節。設計
優勢:code
容易擴展。通常來講,抽象類中的模版方法是不易產生改變的部分,而抽象方法是容易產生變化的部分。所以經過增長實現類能夠實現功能的擴展,符合開閉原則。繼承
便於維護。對於模版方法模式來講,正是因爲他們的主要邏輯相同,才使用了模版方法。所以維護起來很方便
比較靈活。由於有鉤子方法,所以,子類的實現也能夠影響到父類中主邏輯的運行。
缺點
在靈活的同時,因爲子類影響到了父類,因此違反了里氏替換原則,會給程序帶來風險。這就對抽象類的設計有了更高的要求。這也是java三大特色中繼承這個特色的通病。
該模式也違反了面向接口編程。
適用場景
在多個子類擁有相同的方法,而且這些方法邏輯相同時,能夠考慮適用模版方法模式。
在程序的主框架相同,細節不一樣的場景下,也比較適合使用這種模式。
public class TestPaperMain { public static void main(String[] args) { TestPaperA a=new TestPaperA(); a.question1(); a.question2(); a.question3(); TestPaperB b=new TestPaperB(); b.question1(); b.question2(); b.question3(); } } class TestPaperA extends TestPaper { @Override public String anser1() { return "a"; } @Override public String anser2() { return "b"; } @Override public String anser3() { return "12"; } } class TestPaperB extends TestPaper { @Override public String anser1() { return "2"; } @Override public String anser2() { return "4"; } @Override public String anser3() { return "5"; } } abstract class TestPaper { public void question1() { System.out.println("1+1=?"); System.out.println("答案是" + anser1()); } public void question2() { System.out.println("2*2=?"); System.out.println("答案是" + anser2()); } public void question3() { System.out.println("8-3=?"); System.out.println("答案是" + anser3()); } public abstract String anser1(); public abstract String anser2(); public abstract String anser3(); }