新聞中心
建造者模式是日常開發(fā)中比較常見的設(shè)計(jì)模式,它的主要作用就是將復(fù)雜事物創(chuàng)建的過程抽象出來,該抽象的不同實(shí)現(xiàn)方式不同,創(chuàng)建出的對象也不同。

一、前言
今天我們討論一下 Builder 建造者模式,這個(gè) Builder,其實(shí)和模板模式非常的像,但是也有區(qū)別,那就是在模板模式中父類對子類中的實(shí)現(xiàn)進(jìn)行操作,在父類之中進(jìn)行一件事情的處理,但是在 Builder 模式之中,父類和子類都不用關(guān)心怎么處理,而是用另一個(gè)類來完成對這些方法的有機(jī)組合,這個(gè)類的職責(zé)就是監(jiān)工,規(guī)定了到底要怎么樣有機(jī)的組合這些方法。在監(jiān)工類(Director)中,將父類組合進(jìn)去,然后調(diào)用父類的操作來抽象的實(shí)現(xiàn)一件事情,這就是面向接口(抽象)變成的妙處了,當(dāng)然這個(gè) Builder 可以使接口也可以是抽象類,在這里我們使用抽象類。
二、Builder 模式代碼
Builder 抽象類
Builder.java
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 實(shí)現(xiàn)類
HtmlBuilder.java
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class HtmlBuilder extends Builder {
private String filename;
private PrintWriter pw;
public void makeTitle(String title) {
filename="D:\\"+title+".html";
try {
pw=new PrintWriter(new FileWriter(filename));
} catch (IOException e) {
e.printStackTrace();
}
pw.println(""+title+"");
pw.println(""
+title+"");
}
public void makeString(String str) {
pw.println(""
+str+"");
}
public void makeItems(String[] items) {
pw.println("
"
);
for(int i=0;i
"
"+items[i]+" "); } pw.println(
""); } public void
close() { pw.println(
""); pw.close(); } public String
getResult(){
return filename; } }
TextBuilder 實(shí)現(xiàn)類
TextBuilder.java
public class TextBuilder extends Builder {
StringBuffer sb=new StringBuffer();
public void makeTitle(String title) {
sb.append("=====================");
sb.append("["+title+"]"+"\n");
}
public void makeString(String str) {
sb.append("@"+str+"\n");
}
public void makeItems(String[] items) {
for(int i=0;i
" ."+items[i]+
"\n"); } } public void
close() { sb.append(
"====================="); } public String
getResult(){
return sb.toString(); } }
Director 監(jiān)工類
Director.java
public class Director {
private Builder builder;
public Director(Builder builder){
this.builder=builder;
}
public void construct(){
String [] items1=new String[]{"奏國歌","升國旗"};
String [] items2=new String[]{"觀眾鼓掌","有序撤離"};
builder.makeTitle("今日頭條");
builder.makeString("畢業(yè)典禮");
builder.makeItems(items1);
builder.makeString("典禮結(jié)束");
builder.makeItems(items2);
builder.close();
}
}
Main 類
Director.java
public class Main {
public static void main(String[] args) {
//String choice="plain";
String choice="html";
if(choice=="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());
}else{
usage();
}
}
private static void usage() {
System.out.println("使用 plain,編輯文本文件");
System.out.println("使用 html,編輯網(wǎng)頁文件");
}
}
運(yùn)行結(jié)果
三、總結(jié)
關(guān)于Builder模式,我們一定要分清和模板方法的區(qū)別,其實(shí)就是到底誰承擔(dān)了”監(jiān)工”的責(zé)任,在模板方法中父類承擔(dān)了這個(gè)責(zé)任,而在Builder中,有另外一個(gè)專門的類來完成這樣的操作,這樣做的好處是類的隔離,比如說在Main中,用戶根本就不知道有Builder這個(gè)抽象類,同樣的Director這個(gè)監(jiān)工的根本就不管到底是哪一個(gè)實(shí)現(xiàn)類,因?yàn)槿魏我粋€(gè)都會被轉(zhuǎn)換為父類,然后進(jìn)行處理(面向抽象編程的思想),因此很好的實(shí)現(xiàn)了隔離,同樣的這樣設(shè)計(jì)的好處是復(fù)用了,隔離的越好復(fù)用起來就越方便,我們完全可以思考,假如還有另外一個(gè)監(jiān)工,使用了不同的construct方法來組裝這些復(fù)雜的事件,那么對于原來的代碼我們不用做任何的修改,只用增加這樣的一個(gè)監(jiān)工類,然后定義好相應(yīng)的方法就好了,之后再M(fèi)ain中使用,這樣的一種思想使得我們不用修改源代碼,復(fù)用(Builder以及其子類)就很方便了,同樣的,如果想增加一個(gè)新的Builder的子類,只要照著父類的方法進(jìn)行填充,再加上自己的方法就好了,完全不用修改代碼,這也是一種復(fù)用,因此這種復(fù)用(組件)的思想在設(shè)計(jì)模式中隨處可見,本質(zhì)就是高內(nèi)聚低耦合,組件開發(fā),盡量不修改原來的代碼,有可擴(kuò)展性,理解了這一點(diǎn),我們再看看模板方法,責(zé)任全放在了父類里,如果責(zé)任需要改變,則必須要修改父類中的責(zé)任方法了,這樣就修改了原來的代碼,不利于復(fù)用,這也是兩者的本質(zhì)區(qū)別。
當(dāng)前標(biāo)題:講解一下設(shè)計(jì)模式:Builder模式
轉(zhuǎn)載來于:http://fisionsoft.com.cn/article/dhcgged.html


咨詢
建站咨詢
