1. Preface

Today we discuss the Builder pattern. This Builder is actually very similar to the Template pattern, but there are differences. That is, in the Template pattern, the parent class operates on the implementations in the subclasses and handles a task within the parent class. However, in the Builder pattern, neither the parent class nor the subclasses care about how to handle it; instead, another class is used to complete the organic combination of these methods. The responsibility of this class is:supervisor, which specifies exactly how to organically combine these methods. In the supervisor class (Director), the parent class is composed in, and then the parent class's operations are called to abstractly accomplish a task. This is the beauty of interface-oriented (abstract) programming. Of course, this Builder can be an interface or an abstract class; here we use an abstract class.

2. Builder Pattern Code

Builder abstract class:

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 implementation class:

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 implementation class:

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

Director.java

public class Director { private Builder builder; public Director(Builder builder){ this.builder=builder; } public void construct(){ String [] items1=new String[]{"Play the national anthem","Raise the national flag"}; String [] items2=new String[]{"The audience applauds","Evacuate in an orderly manner"}; builder.makeTitle("Today's Headlines"); builder.makeString("Graduation ceremony"); builder.makeItems(items1); builder.makeString("Ceremony ends"); builder.makeItems(items2); builder.close(); } }

Main class:

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("Use plain to edit text file"); System.out.println("Use html to edit web page file"); } }

Running Results

Or:

3. Summary

Regarding the Builder pattern, we must clearly distinguish it from the Template method pattern. In fact, it comes down to who takes on the responsibility of the "supervisor". In the Template method pattern, the parent class assumes this responsibility, while in Builder, there is another dedicated class to complete such operations. The benefit of this is class isolation. For example, in Main, the user has no idea that the Builder abstract class exists; similarly, the Director (supervisor) does not care at all which implementation class it is, because any one of them will be converted to the parent class and then processed (the idea of abstract-oriented programming). Thus isolation is well achieved. Similarly, this design benefits reuse: the better the isolation, the more convenient the reuse. We can fully imagine that if there is another supervisor that uses a different construct method to assemble these complex events, then we do not need to make any modifications to the original code; we only need to add such a supervisor class, define the corresponding methods, and then use it in Main. This kind of idea allows us to avoid modifying source code, making reuse (Builder and its subclasses) very convenient. Similarly, if we want to add a new subclass of Builder, we just fill in according to the methods of the parent class and add our own methods, without modifying the code at all. This is also a form of reuse. Therefore, this idea of reuse (components) can be seen everywhere in design patterns. Its essence is high cohesion and low coupling, component development, trying not to modify the original code, and having extensibility. Once we understand this, let's look at the Template method again: the responsibility is all placed in the parent class. If the responsibility needs to change, the responsibility method in the parent class must be modified; this modifies the original code and is not conducive to reuse. This is also the essential difference between the two.

Original address: https://www.cnblogs.com/zyrblog/p/9230630.html