設計模式:Builder模式概述

大雄45發表於2021-02-05
導讀 Builder模式是程式碼編寫過程中經常會用到的一類設計模式。目的是將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。
一、前言

今天我們討論一下 Builder 建造者模式,這個 Builder,其實和模板模式非常的像,但是也有區別,那就是在模板模式中父類對子類中的實現進行操作,在父類之中進行一件事情的處理,但是在 Builder 模式之中,父類和子類都不用關心怎麼處理,而是用另一個類來完成對這些方法的有機組合,這個類的職責就是監工,規定了到底要怎麼樣有機的組合這些方法。在監工類(Director)中,將父類組合進去,然後呼叫父類的操作來抽象的實現一件事情,這就是面向介面(抽象)變成的妙處了,當然這個 Builder 可以使介面也可以是抽象類,在這裡我們使用抽象類。
設計模式:Builder模式概述設計模式: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 實現類

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("<html><head><title>"+title+"</title></head><body>");        pw.println("<h1>"+title+"</h1>");    }
    
    public void makeString(String str) {
        pw.println("<p>"+str+"</p>");    }
 
    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>");    }
 
    public void close() {
        pw.println("</body></html>");        pw.close();    }
    public String getResult(){
        return filename;    }}
TextBuilder 實現類

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.length;i++){
            sb.append("   ."+items[i]+"\n");        }
    }
 
    public void close() {
        sb.append("=====================");    }
    
    public String getResult(){
        return sb.toString();    }
    }
Director 監工類

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("畢業典禮");        builder.makeItems(items1);        builder.makeString("典禮結束");        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,編輯網頁檔案");    }
 }

執行結果
設計模式:Builder模式概述設計模式:Builder模式概述
設計模式:Builder模式概述設計模式:Builder模式概述
設計模式:Builder模式概述設計模式:Builder模式概述

三、總結

關於Builder模式,我們一定要分清和模板方法的區別,其實就是到底誰承擔了"監工"的責任,在模板方法中父類承擔了這個責任,而在Builder中,有另外一個專門的類來完成這樣的操作,這樣做的好處是類的隔離,比如說在Main中,使用者根本就不知道有Builder這個抽象類,同樣的Director這個監工的根本就不管到底是哪一個實現類,因為任何一個都會被轉換為父類,然後進行處理(面向抽象程式設計的思想),因此很好的實現了隔離,同樣的這樣設計的好處是複用了,隔離的越好複用起來就越方便,我們完全可以思考,假如還有另外一個監工,使用了不同的construct方法來組裝這些複雜的事件,那麼對於原來的程式碼我們不用做任何的修改,只用增加這樣的一個監工類,然後定義好相應的方法就好了,之後再Main中使用,這樣的一種思想使得我們不用修改原始碼,複用(Builder以及其子類)就很方便了,同樣的,如果想增加一個新的Builder的子類,只要照著父類的方法進行填充,再加上自己的方法就好了,完全不用修改程式碼,這也是一種複用,因此這種複用(元件)的思想在設計模式中隨處可見,本質就是高內聚低耦合,元件開發,儘量不修改原來的程式碼,有可擴充套件性,理解了這一點,我們再看看模板方法,責任全放在了父類裡,如果責任需要改變,則必須要修改父類中的責任方法了,這樣就修改了原來的程式碼,不利於複用,這也是兩者的本質區別。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2756213/,如需轉載,請註明出處,否則將追究法律責任。

相關文章