"Design mode - Builder mode"

"Design mode (VI) - Builder mode"

1, Customizable

The assembly of computers is no stranger in life. Everyone has computers. Of course, the needs and configuration are different. Take Macbook Pro as an example. For example, UI design has high requirements for GPU of image module, while running IDEA has high requirements for memory. 32G memory may be added, and 64G memory is higher. If it is to deal with daily office and drama brushing, the default configuration is enough, such as 8G standard configuration. Similarly, in the process of software development, you need to customize and match different options to build objects according to your needs. Generally, you can use the Builder mode to explain it well and see what the specific definition is.

2, Builder mode

Wikipedia

The builder pattern is a design pattern designed to provide a flexible solution to various object creation problems in object-oriented programming. The intent of the Builder design pattern is to separate the construction of a complex object from its representation. It is one of the Gang of Four design patterns.

Popular representation: that is, the construction of a complex object is separated from the representation. In the same construction process, different representations can be created according to needs. It is called Builder mode or Builder mode.

3, Structural composition
  • Structure class diagram:

  • Constructor Interface Builder: it usually contains the abstract method of building part module and the result method getResult() after object creation.

  • Constructor implementation class ConcreteBuilder: the concrete implementation of the Builder interface, build various parts of the Product, assemble them into a complete Product object, and return the specific object through * * getResult() *.

  • Abstract interface of Product: the object to be constructed, which generally contains multiple components to form a more complex object.

  • Customizer (Director): determines the specific creation composition of the Product, such as what components are included. Guide the creation of Product complex objects, and the class diagram is relatively clear; Generally, Builder is used to complete the creation process.

4, Code implementation
1. Design a simple file export system

Configure the corresponding document system and export files as needed, such as exporting plain text content * * text**,. html and other files.

  • The Element element corresponds to the Product here, that is, the interface of the Product
public interface Element {
  //no method
}

1. In order to provide default methods, the implementation class decides what details to implement.

  • Element concrete implementation class - text
/**
 * Created by Sai
 * on: 25/01/2022 00:48.
 * Description:
 */
public class Text implements Element {
    private final String content;

    public Text(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }
}
  • Concrete implementation class of Element - picture
/**
 * Created by Sai
 * on: 25/01/2022 00:49.
 * Description:
 */
public class Image implements Element {
    private final String source;

    public Image(String source) {
        this.source = source;
    }

    public String getSource() {
        return source;
    }
}
  • Builder interface builder. Since it is a builder of document type, it is DocumentBuilder if the naming is standardized, the same below:
/**
 * Created by Sai
 * on: 25/01/2022 00:52.
 * Description:
 */
public interface DocumentBuilder {
    void addText(Text text);

    void addImage(Image image);

    String getResult();
}

1. Two methods for adding content are provided, addText and addImage.

2. Provide a method to return specific content, getResult.

  • Concrete implementation of Builder - plain text document builder
public class TextDocumentBuilder implements DocumentBuilder {

    private final StringBuilder builder = new StringBuilder();

    @Override
    public void addText(Text text) {
        builder.append(text.getContent());
    }

    @Override
    public void addImage(Image image) {
        //empty implements
    }

    @Override
    public String getResult() {
        return builder.toString();
    }
}

1. The plain text content does not support adding pictures. The method of adding pictures is not implemented and is empty.

  • Because the html structure is more complex than plain text, including tags, paragraphs, etc., if it is completely dependent on Element, it is not conducive to expansion and implementation is more troublesome. Therefore, for html type document files, it is necessary to implement its own set of Element components separately. Add it dynamically with Element as the medium.

  • Implement html specific element HtmlElement separately

public class HtmlElement {
  //empty method
}
  • Html picture element component HtmlImage inherits from HtmlElement
public class HtmlImage extends HtmlElement {
    private final String source;

    public HtmlImage(String source) {
        this.source = source;
    }

    @Override
    public String toString() {
        return String.format("<img src=\"%s\" />", source);
    }
}
  • Html paragraph text component HtmlParagraph also inherits from HtmlElement
public class HtmlParagraph extends HtmlElement {
    private final String text;

    public HtmlParagraph(String text) {
        this.text = text;
    }

    @Override
    public String toString() {
        return String.format("<p>%s</p>", text);
    }
}
  • A complete HTML document may contain a variety of collections of HtmlParagraph and HtmlImage, and define the HTML document class - HtmlDocument
public class HtmlDocument {
    private final List<HtmlElement> elements = new ArrayList<>();

    public void add(HtmlElement element) {
        elements.add(element);
    }

    @Override
    public String toString() {
        var builder = new StringBuilder();
        builder.append("<html>");
        for (HtmlElement element : elements)
            builder.append(element.toString());
        builder.append("</html>");
        return builder.toString();
    }
}
  • For the implementation of html Builder: due to the particularity of html documents, although the DocumentBuilder interface needs to be implemented according to the implementation process of class diagram, it is obvious that only the methods in DocumentBuilder can not meet the customization requirements, However, when combined with redefining a set of html document assembly rules * * (HtmlDocument, HtmlElement, HtmlImage, HtmlParagraph) * *, the extension can be well completed:
public class HtmlDocumentBuilder implements DocumentBuilder {
    
    private final HtmlDocument document = new HtmlDocument();

    @Override
    public void addText(Text text) {
        document.add(new HtmlParagraph(text.getContent()));
    }

    @Override
    public void addImage(Image image) {
        document.add(new HtmlImage(image.getSource()));
    }

    @Override
    public String getResult() {
        return document.toString();
    }
}
  • Complete document export class - Document
public class Document {
    private final List<Element> elements = new ArrayList<>();

    public void add(Element element) {
        elements.add(element);
    }

    public void export(DocumentBuilder builder, String fileName) throws IOException {
        for (Element element : elements) {
            if (element instanceof Text)
                builder.addText((Text) element);
            else if (element instanceof Image)
                builder.addImage((Image) element);
        }
        var writer = new FileWriter(fileName);
        writer.write(builder.getResult());
        writer.close();
    }
}
  • Test Demo
public class Demo {
    public static void show() throws IOException {
        var document = new Document();
        document.add(new Text("\n\n\n\n Happy two dogs🐶🐶🐶\nphp Is the best language🐶\n"));
        document.add(new Image("pic1.jpg"));

        document.export(new HtmlDocumentBuilder(), "sai.html");
        //Document does not add pictures
        document.export(new TextDocumentBuilder(), "sai.txt");
    }

    public static void main(String[] args) throws IOException {
        show();
    }
}

1. Simply add a text content and a "picture content" to form a plain text document and an Html document respectively, but the text document does not add a picture.

2. The exported files are in the same package, Sai HTML and Sai Text file.

  • Plain text document content

  • html document

2. Consideration on advantages, disadvantages and limitations

1. The builder mode well separates the construction from the performance. The client or Director can flexibly choose according to needs to produce different products under the same set of construction algorithm, so as to reduce the coupling between the performance and production.

2. The specific construction details are included in the system. The client only needs to call the Builder interface to create the required objects, which reduces the risk of system error.

3. Enhanced code reusability.

4. Of course, the disadvantages are also obvious. If the object is too complex and there are too many assembled parts, it is often difficult to control, resulting in bloated and unclear structure.

5. If the original realization of the product is changed, the whole process needs to be adjusted accordingly. Assuming that the product itself is too complex, it is very unfavorable for later maintenance. When considering the use, it should be based on the actual situation. It is not suitable for complex and frequently changing objects.

5, Deformation in practical application

In the actual use process, the standardized construction process is often simplified. Of course, according to the specific business scenario, the Director guidance class, Builder interface and specific ConcreteBuilder implementation class are generally omitted, and the Builder is directly implemented in the target product class as an internal class. Different products can be obtained according to the choice of the caller. Of course, this kind is relatively simple, which can be said to be the simplest one. It's just an application of ideas, or it's also a kind of * * "trick" * * practice.

  • Customization of simple filter objects in their own projects:
public class FilterGroup {
    private int id;
    private String title;
    private boolean supportMultiSelected;
    private List<FilterOrderDTO> filterFactors;

    private FilterGroup(Builder builder) {
        if (builder == null) {
            return;
        }
        this.id = builder.id;
        this.title = builder.title;
        this.supportMultiSelected = builder.supportMultiSelected;
        this.filterFactors = builder.filterFactors;
    }

    public int getId() {
        return id;
    }

    public String getTitle() {
        return title;
    }

    public boolean isSupportMultiSelected() {
        return supportMultiSelected;
    }

    public List<FilterOrderDTO> getFilterFactors() {
        return filterFactors;
    }

    public static class Builder {
        private int id;
        private String title;
        private boolean supportMultiSelected;
        private List<FilterOrderDTO> filterFactors;

        public Builder setId(int id) {
            this.id = id;
            return this;
        }

        public Builder setTitle(String title) {
            this.title = title;
            return this;
        }

        public Builder setSupportMultiSelected(boolean supportMultiSelected) {
            this.supportMultiSelected = supportMultiSelected;
            return this;
        }

        public Builder setFilterFactors(List<FilterOrderDTO> filterFactors) {
            this.filterFactors = filterFactors;
            return this;
        }

        public FilterGroup build() {
            return new FilterGroup(this);
        }
    }
}

1.Builder exists in the interior of products in the form of static internal classes, and the characteristics of products are: different products corresponding to different construction components have different properties. Secondly, the builder only provides the set method, not the get method.

2. The construction method of the target product FilterGroup is private and takes Builder as the parameter. In addition, only the get method is provided, not the set method.

3. That is, the construction of the target product is completed through Builder, which is only "readable" for users.

4. As in the actual development, the Builder mode can be considered when the product is built in parts and separated from the whole. The core idea is the separation between the whole construction and parts, and the coupling between the loose product construction and the product representation.

Keywords: Design Pattern

Added by Xager on Tue, 25 Jan 2022 03:59:11 +0200