1、前言html
Builder建造者模式和模板模式很是像,可是也有區別,模板模式中父類對子類中的實現進行操做,在父類之中進行一件事情的處理,可是在Builder模式之中,父類和子類都不用關心怎麼處理,而是用另外一個類來完成對這些方法的有機組合,這個類的職責就是‘監工’,規定了到底要怎麼樣有機的組合這些方法。在監工類(Director)中,將父類組合進去,而後調用父類的操做來抽象的實現一些事情,這就是面向接口(抽象)的妙處,固然這個Builder能夠是接口也能夠是抽象類,在這裏咱們使用抽象類。java
2、Builder模式代碼編程
Builder抽象類:設計模式
package designMode.builder; public abstract class Builder { public abstract void makeString(String str); public abstract void makeTitle(String title); public abstract void makeItems(String[] items); public abstract void close(); }
HtmlBuilder實現類:app
package designMode.builder; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class HtmlBuilder extends Builder { private String filename; private PrintWriter pw; @Override public void makeString(String str) { pw.println("<p>"+str+"</p>"); } @Override public void makeTitle(String title) { filename = "D:\\"+title+".html"; try { pw = new PrintWriter(new FileWriter(filename)); } catch (IOException e) { e.printStackTrace(); } pw.println("<html><head><title>"+title+"</title></head><body>"); pw.println("<h1>"+title+"</h1>"); } @Override public void makeItems(String[] items) { pw.println("<ul>"); for(int i=0;i<items.length;i++){ pw.println("<li>"+items[i]+"</li>"); } pw.println("</ul>"); } @Override public void close() { pw.println("</body></html>"); pw.close(); } public String getResult() { return filename; } }
TextBuilder實現類: ide
package designMode.builder; public class TextBuilder extends Builder{ StringBuffer sb=new StringBuffer(); @Override public void makeString(String str) { sb.append("@"+str+"\n"); } @Override public void makeTitle(String title) { sb.append("====================="); sb.append("["+title+"]"+"\n"); } @Override public void makeItems(String[] items) { for(int i=0;i<items.length;i++){ sb.append(" ."+items[i]+"\n"); } } @Override public void close() { sb.append("====================="); } public String getResult(){ return sb.toString(); } }
Director監工類: ui
package designMode.builder; public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } public void construct(){ String[] items = new String[]{"奏國歌","升國旗"}; String [] items2=new String[]{"觀衆鼓掌","有序撤離"}; builder.makeTitle("今日頭條"); builder.makeString("畢業典禮"); builder.makeItems(items); builder.makeString("典禮結束"); builder.makeItems(items2); builder.close(); } }
Main類:this
package designMode.builder; public class BuilderMain { public static void main(String[] args) { //String choice="plain"; String choice="html"; if(choice.equals("plain")){ TextBuilder t = new TextBuilder(); Director d = new Director(t); d.construct(); System.out.println(t.getResult()); }else if(choice=="html"){ HtmlBuilder html = new HtmlBuilder(); Director d = new Director(html); d.construct(); System.out.println(html.getResult()); } } }
3、運行結果spa
4、總結.net
關於Builder模式,咱們必定要分清和模板模式的區別,其實就是到底誰承擔了「監工」的責任,在模板模式中父類承擔了這個責任,在builder模式中,有另一個專門的類來完成這樣的操做,這樣的好處是類的隔離,好比說在main中,用戶根本就不知道builder這個抽象類,一樣的Director這個監工根本就無論是哪個實現類,由於任何一個都會被轉換爲父類,而後進行處理(面向抽象編程的思想),所以很好的實現了隔離,一樣的這樣設計的好處是複用,隔離的越好複用起來越方便,咱們徹底能夠思考,假如還有另一個監工,使用了不一樣的construct方法來組裝這些複雜的事件,那麼對於原來的代碼不用作任何的修改,只需增長這樣一個監工類便可,而後定義好相應的方法就行了,以後再main中使用,這樣的一種思想使得咱們不用修改源代碼,複用(builder及其子類)就很方便了,一樣的,若是想增長一個builder子類,只要照着父類的方法進行填充,再加上本身的方法就行了,徹底不用修改代碼,這也是一種複用,所以這種複用的思想在設計模式中隨處可見,本質就是高內聚低耦合,組件開發,儘可能不修改原來的代碼,有擴展性,理解了這一點,咱們再看看模板方法,責任全放在父類裏,若是責任須要改變,則必需要修改父類中的責任方法了,這樣就修改了原來的代碼,不利於複用,這也是二者的本質區別。