1. Vorwort

Heute besprechen wir das Builder-Muster. Dieser Builder ist dem Template-Muster tatsächlich sehr ähnlich, aber es gibt Unterschiede. Das heißt, im Template-Muster arbeitet die Elternklasse mit den Implementierungen in den Unterklassen und erledigt eine Aufgabe innerhalb der Elternklasse. Im Builder-Muster hingegen kümmert sich weder die Elternklasse noch die Unterklassen darum, wie damit umgegangen wird; stattdessen wird eine andere Klasse verwendet, um die organische Kombination dieser Methoden zu vervollständigen. Die Verantwortung dieser Klasse ist:Supervisor, der genau festlegt, wie diese Methoden organisch kombiniert werden. In der Supervisor-Klasse (Director) wird die Elternklasse eingebunden, und dann werden die Operationen der Elternklasse aufgerufen, um abstrakt eine Aufgabe zu erledigen. Das ist die Schönheit der schnittstellenorientierten (abstrakten) Programmierung. Natürlich kann dieser Builder eine Schnittstelle oder eine abstrakte Klasse sein; hier verwenden wir eine abstrakte Klasse.

2. Builder-Muster-Code

Abstrakte Klasse 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 Implementierungsklasse:

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-Implementierungsklasse:

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-Supervisor-Klasse:

Director.java

public class Director { private Builder builder; public Director(Builder builder){ this.builder=builder; } public void construct(){ String [] items1=new String[]{"Spiele die Nationalhymne","Die Nationalflagge hissen"}; String [] items2=new String[]{"Das Publikum applaudiert","Geordnet evakuieren"}; builder.makeTitle("Heutige Schlagzeilen"); builder.makeString("Abschlussfeier"); builder.makeItems(items1); builder.makeString("Die Feier endet"); builder.makeItems(items2); builder.close(); } }

Hauptklasse:

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("Verwenden Sie plain, um eine Textdatei zu bearbeiten"); System.out.println("Verwenden Sie html, um eine Webseitendatei zu bearbeiten"); } }

Ausführungsergebnisse

Oder:

3. Zusammenfassung

Beim Builder-Muster müssen wir es klar vom Template-Methoden-Muster unterscheiden. Tatsächlich läuft es darauf hinaus, wer die Verantwortung des "Supervisors" übernimmt. Beim Template-Methoden-Muster übernimmt die Elternklasse diese Verantwortung, während es beim Builder eine andere dedizierte Klasse gibt, die solche Operationen ausführt. Der Vorteil davon ist die Klassenisolation. Zum Beispiel hat der Benutzer in Main keine Ahnung, dass die abstrakte Klasse Builder existiert; ebenso ist es dem Director (Supervisor) völlig egal, welche Implementierungsklasse es ist, denn jede von ihnen wird in die Elternklasse umgewandelt und dann verarbeitet (die Idee der abstraktionsorientierten Programmierung). So wird Isolation gut erreicht. Ebenso profitiert dieses Design von Wiederverwendung: Je besser die Isolation, desto bequemer die Wiederverwendung. Wir können uns gut vorstellen, dass wir, wenn es einen anderen Supervisor gibt, der eine andere Konstruktionsmethode verwendet, um diese komplexen Ereignisse zusammenzusetzen, dann keine Änderungen am ursprünglichen Code vornehmen müssen; wir müssen nur eine solche Supervisor-Klasse hinzufügen, die entsprechenden Methoden definieren und sie dann in Main verwenden. Diese Art von Idee erlaubt es uns, den Quellcode nicht zu ändern, was die Wiederverwendung (Builder und seine Unterklassen) sehr bequem macht. Ebenso: Wenn wir eine neue Unterklasse von Builder hinzufügen möchten, füllen wir einfach entsprechend den Methoden der Elternklasse aus und fügen unsere eigenen Methoden hinzu, ohne den Code überhaupt zu ändern. Auch das ist eine Form der Wiederverwendung. Daher ist diese Idee der Wiederverwendung (Komponenten) überall in Entwurfsmustern zu sehen. Ihr Wesen ist hohe Kohäsion und geringe Kopplung, Komponentenentwicklung, der Versuch, den ursprünglichen Code nicht zu ändern, und Erweiterbarkeit. Sobald wir das verstehen, schauen wir uns das Template-Methoden-Muster noch einmal an: Die Verantwortung liegt vollständig bei der Elternklasse. Wenn sich die Verantwortung ändern muss, muss die Verantwortungsmethode in der Elternklasse geändert werden; das ändert den ursprünglichen Code und ist nicht förderlich für die Wiederverwendung. Das ist auch der wesentliche Unterschied zwischen den beiden.

Originaladresse: https://www.cnblogs.com/zyrblog/p/9230630.html