I. Preface
Builder builder pattern and template pattern are very similar, but there are differences. In template pattern, the parent class operates on the implementation of the child class and handles one thing in the parent class. But in Builder pattern, the parent class and the child class do not care about how to handle it, but use another class to complete these methods. Unit combination, the responsibility of this category is "supervisor", which specifies how to organically combine these methods. In Director, we combine the parent class and call the operation of the parent class to abstract some things. This is the beauty of Interface-oriented (abstract). Of course, this builder can be either an interface or an abstract class. Here we use abstract class.
Builder pattern code
Builder Abstract class:
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 implementation class:
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 implementation class:
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 supervisor class:
package designMode.builder; public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } public void construct(){ String[] items = new String[]{"Play the National Anthem","Raising of the national flag"}; String [] items2=new String[]{"Applause from audience","Orderly evacuation"}; builder.makeTitle("Today's headlines"); builder.makeString("Graduation ceremony"); builder.makeItems(items); builder.makeString("The ceremony is over."); builder.makeItems(items2); builder.close(); } }
Class Main:
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. Operation results
Four, summary
As for the Builder pattern, we must distinguish it from the template pattern. In fact, who is responsible for the "supervisor". In the template pattern, the parent class assumes the responsibility. In the builder pattern, there is another special class to do this. The advantage is the separation of classes, for example, in the main mode. Users don't know the abstract class builder. The same Director supervisor doesn't care which implementation class it is, because any one of them will be transformed into a parent class and then processed (the idea of abstract programming). Therefore, isolation is well realized. The advantage of the same design is reuse. The better the isolation, the more convenient it is to reuse, we can think that if there is another supervisor who uses different construct methods to assemble these complex events, then no modification is needed to the original code, just add such a supervisor class, and then define the corresponding method. Then we use it in main. This idea makes it easy for us to reuse (builder and its subclasses) without modifying the source code. Similarly, if we want to add a builder subclass, we just need to fill it in according to the method of the parent class, and add our own method, so we don't need to modify the code at all. It is a kind of reuse, so the idea of reuse can be seen everywhere in the design pattern. The essence of reuse is high cohesion and low coupling, component development, try not to modify the original code, scalability. Understanding this, let's look at the template method. The responsibility is all in the parent class. If the responsibility needs to be changed, it must be modified. The responsibility method in the parent class changes the original code, which is not conducive to reuse, which is also the essential difference between the two.