Design Patterns - In-depth Explanation of Builder Patterns

3.4 Builder Mode

Definition: The Builder Pattern is also called the Builder Pattern. In actual development, when the objects we need are very complicated to construct, and there are many steps to be processed, the Builder Pattern is very suitable. For example, in the creation of the SqlSessionFactory object in MyBatis, we not only need to create the object of the SqlSessionFactory itself, but also complete the loading and parsing operations of the global configuration file and mapping file of MyBatis, and then bind the parsed information to the SqlSessionFactory object.

Refer to the code of MyBatis


advantage:

  • Good encapsulation, separation of creation and use;
  • Good extensibility, independent and decoupled to a certain extent between construction classes.
    question:
  • Generate redundant Builder objects;
  • If the product changes internally, the builder has to modify it, and the cost is relatively large.

3.4.1 Role:

  • builder (abstract builder): Specifies an abstract interface for the components that create a product object.
  • ConcreteBuilder (concrete builder): Implements the Builder's interface to construct and assemble the various components of the product, define and clarify the representation it creates, and provide an interface for retrieving the product.
  • Director: Constructs an object using the Builder interface. It has two main functions, one is: isolating the production process of customers and objects, and the other is: responsible for controlling the production process of product objects.
  • Product: Represents a complex object that is constructed. ConcreteBuilder creates an internal representation of the product and defines its assembly process, including defining the classes that make up the components, including the interfaces for assembling these components into the final product.

3.4.2 Usage scenarios

  • The product class is very complex, or the calling sequence in the product class produces different performances
  • Multiple components or parts can be assembled into an object, but the results are not the same
  • When initializing an object was particularly complicated, with many parameters, and many parameters had default values
  • Some other objects in the system are used during the object creation process, and these objects are not easily available during the creation of the product object (requires multiple lines of code).

3.3.3 Code Implementation

/**
 * @Description Learning Abstract Classes (Product Classes)
 * @Auther nine stop
 * Date 2022/10/3 16:46
 */
public abstract class Study {
    /**
     * Learning Order Parameters
     */
    private ArrayList<String> sequence = new ArrayList<>();

    /**
     * study by reading
     */
    public abstract void studyByBook();

    /**
     * watch video learning
     */
    public abstract void studyByVideo();

    /**
     * Brush questions
     */
    public abstract void brushQuestion();

    /**
     * review
     */
    public abstract void review();

    /**
     * Execute the study plan
     */
    final public void execute() {
        this.sequence.forEach(item->{
            switch(item)
            {
                case "studyByBook":
                    this.studyByBook();
                    break;
                case "studyByVideo":
                    this.studyByVideo();
                    break;
                case "brushQuestion":
                    this.brushQuestion();
                    break;
                case "review":
                    this.review();
                    break;
                default:
                    throw new RuntimeException("Tip: The study plan is wrong!");
            }
        });
    }

    public ArrayList<String> getSequence() {
        return sequence;
    }

    public void setSequence(ArrayList<String> sequence) {
        this.sequence = sequence;
    }
}

//=============================================================================

/**
 * @Description English learning class (product class)
 * @Auther nine stop
 * Date 2022/10/3 17:01
 */
public class EnglishStudy extends Study{
    @Override
    public void studyByBook() {
        System.out.println("Start learning English by reading books...");
    }

    @Override
    public void studyByVideo() {
        System.out.println("Start learning English by watching videos...");
    }

    @Override
    public void brushQuestion() {
        System.out.println("Start learning English by brushing questions...");
    }

    @Override
    public void review() {
        System.out.println("Start learning English by reviewing…");
    }
}

//=============================================================================

/**
 * @Description Mathematics Learning Class (Product Class)
 * @Auther nine stop
 * Date 2022/10/3 17:01
 */
public class MathStudy extends Study{
    @Override
    public void studyByBook() {
        System.out.println("Start learning math by reading...");
    }

    @Override
    public void studyByVideo() {
        System.out.println("Start learning math by watching videos...");
    }

    @Override
    public void brushQuestion() {
        System.out.println("Start learning math by brushing...");
    }

    @Override
    public void review() {
        System.out.println("Start learning math by reviewing…");
    }
}

/**
 * @Description Learning Plan Abstract Builder (Abstract Builder) Provides methods in this class to set various properties of the product class
 * @Auther nine stop
 * Date 2022/10/3 16:29
 */
public interface StudyPlanBuilder{
    /**
     * Set study order
     * @param sequence
     */
    void setSequence(ArrayList<String> sequence);

    /**
     * get learning object
     * @return
     */
    Study getStudy();
}

//=============================================================================

/**
 * @Description English Learning Plan Builder
 * @Auther nine stop
 * Date 2022/10/3 17:04
 */
public class EnglishStudyPlanBuilder implements StudyPlanBuilder{
    private EnglishStudy englishStudy = new EnglishStudy();

    @Override
    public void setSequence(ArrayList<String> sequence) {
        englishStudy.setSequence(sequence);
    }

    @Override
    public Study getStudy() {
        return this.englishStudy;
    }
}

//=============================================================================

/**
 * @Description Math Learning Plan Builder
 * @Auther nine stop
 * Date 2022/10/3 17:04
 */
public class MathStudyPlanBuilder implements StudyPlanBuilder{
    private MathStudy mathStudy = new MathStudy();

    @Override
    public void setSequence(ArrayList<String> sequence) {
        mathStudy.setSequence(sequence);
    }

    @Override
    public Study getStudy() {
        return this.mathStudy;
    }
}


/**
 * @Description The student class acts as a conductor (leader)
 * @Auther nine stop
 * Date 2022/10/3 17:13
 */
public class Student {
    private final ArrayList<String> sequence = new ArrayList<>();
    private final EnglishStudyPlanBuilder englishStudyPlanBuilder = new EnglishStudyPlanBuilder();
    private final MathStudyPlanBuilder mathStudyPlanBuilder = new MathStudyPlanBuilder();
    private static final String STUDY_BY_BOOK = "studyByBook";
    private static final String REVIEW = "review";
    private static final String STUDY_BY_VIDEO = "studyByVideo";
    private static final String BRUSH_QUESTION = "brushQuestion";

    /**
     * English Study Plan A
     */
    public EnglishStudy englishPlanA() {
        this.sequence.clear();
        this.sequence.add(STUDY_BY_BOOK);
        this.sequence.add(REVIEW);
        this.sequence.add(STUDY_BY_VIDEO);
        this.sequence.add(BRUSH_QUESTION);
        this.englishStudyPlanBuilder.setSequence(this.sequence);
        return (EnglishStudy) this.englishStudyPlanBuilder.getStudy();
    }

    /**
     * English Study Plan B
     */
    public EnglishStudy englishPlanB() {
        this.sequence.clear();
        this.sequence.add(STUDY_BY_BOOK);
        this.sequence.add(STUDY_BY_VIDEO);
        this.sequence.add(BRUSH_QUESTION);
        this.sequence.add(REVIEW);
        this.englishStudyPlanBuilder.setSequence(this.sequence);
        return (EnglishStudy) this.englishStudyPlanBuilder.getStudy();
    }


    /**
     * Mathematics Study Plan A
     */
    public MathStudy mathPlanA() {
        this.sequence.clear();
        this.sequence.add(STUDY_BY_BOOK);
        this.sequence.add(REVIEW);
        this.sequence.add(STUDY_BY_VIDEO);
        this.sequence.add(BRUSH_QUESTION);
        this.mathStudyPlanBuilder.setSequence(this.sequence);
        return (MathStudy) this.mathStudyPlanBuilder.getStudy();
    }

    /**
     * Mathematics Study Plan B
     */
    public MathStudy mathPlanB() {
        this.sequence.clear();
        this.sequence.add(STUDY_BY_BOOK);
        this.sequence.add(STUDY_BY_VIDEO);
        this.sequence.add(BRUSH_QUESTION);
        this.sequence.add(REVIEW);
        this.mathStudyPlanBuilder.setSequence(this.sequence);
        return (MathStudy) this.mathStudyPlanBuilder.getStudy();
    }

}

public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        student.mathPlanA().execute();
        System.out.println("-------------------------");
        student.englishPlanB().execute();
    }
}

3.4.4 Comparison with Factory Pattern

  • The builder pattern pays more attention to the invocation order of methods, and the factory pattern focuses on creating objects.
  • Miscellaneous components, the factory pattern created are the same.
  • The concerns are different. The factory pattern only needs to create the object, while the builder pattern not only needs to create the object, but also knows what parts the object consists of.
  • The builder mode is different according to the order in the construction process, and the final object component composition is also different.

Some of the original texts from the notes of Mr. Ma soldier Deng Pengbo are quoted

Tags: Mybatis Design Pattern

Posted by magmazing on Tue, 04 Oct 2022 10:32:38 +0300