One, foreword

Today we continue with the creation pattern in Java design patterns, the Builder pattern. The topic of the previous design pattern was abstract Factory Pattern of Java Design Pattern (PART 3).

Two, a brief introduction

The Builder/generator pattern is one of the object creation patterns used to hide the creation process of composite objects. It abstracts the creation process of composite objects and dynamically creates objects with composite properties through subclass inheritance and overloading.

The Builder pattern implementation process is usually divided into two steps: Build (Builder) and assemble (Director). The English here is not a translation of Chinese characters but to illustrate the types of interfaces needed for these two steps.

# 2.1 Application Scenario

  1. Object creation: The Builder pattern is a pattern designed for object creation. For example, StringBuilder, DomBuilder, SAXBuilder.

  2. A composite object is created: The object being created is a composite object with composite properties.

  3. Focus on the creation process for each part of object creation: Different factories (Builders) have different ways of creating product properties.

Third, implementation method

Again, let’s take the example of creating a car.

Entity class:

public class Car { private Engine engine; private Tyre tyre; private Seat seat; public void intro() { this.engine.intro(); this.tyre.intro(); this.seat.intro(); } public Engine getEngine() { return engine; } public void setEngine(Engine engine) { this.engine = engine; } public Tyre getTyre() { return tyre; } public void setTyre(Tyre tyre) { this.tyre = tyre; } public Seat getSeat() { return seat; } public void setSeat(Seat seat) { this.seat = seat; }} class Engine {public void intro() {system.out.println (" open fast "); }} class Tyre {public void intro() {system.out.println (" wear-resistant "); }} class Seat {public void intro() {system.out.println (); }}Copy the code

An instance of the Car class is a composite object.

When the builder mode is not used, the client calls the following:

Public class Client {public static void main(String[] args) {Engine Engine = new Engine(); Tyre tyre = new Tyre(); Seat seat = new Seat(); // Assemble Car Car = new Car(); car.setEngine(engine); car.setTyre(tyre); car.setSeat(seat); car.intro(); }}Copy the code

In the above code, the single responsibility principle is violated and the client is coupled to multiple classes, resulting in poor extensibility of the code.

Next we use the Builder pattern to make the code flexible.

Builder interface and implementation classes to implement the build process:

public interface CarBuilder { Engine buildEngine(); Tyre buildTyre(); Seat buildSeat(); } class MyCarBuilder implements CarBuilder { @Override public Engine buildEngine() { return new Engine(); } @Override public Tyre buildTyre() { return new Tyre(); } @Override public Seat buildSeat() { return new Seat(); }}Copy the code

Here the factory pattern is used to create the parts that assemble the car. Most of the time, design patterns are not used alone, but in conjunction with each other.

The Engine, Tyre, and Seat classes have not been abstracted for writing and testing purposes.

Director interface and implementation classes to implement the assembly process:

public interface CarDirector { Car directCar(); } class MyCarDirector implements CarDirector { private CarBuilder carBuilder; public MyCarDirector(CarBuilder carBuilder) { this.carBuilder = carBuilder; } @Override public Car directCar() { Engine engine = this.carBuilder.buildEngine(); Tyre tyre = this.carBuilder.buildTyre(); Seat seat = this.carBuilder.buildSeat(); // assemble Car Car = new Car(); car.setEngine(engine); car.setTyre(tyre); car.setSeat(seat); return car; }}Copy the code

Hide the creation of composite objects (Car instances) through the directCar method.

Client:

public class Client { public static void main(String[] args) { CarDirector director = new MyCarDirector(new MyCarBuilder()); Car car = director.directCar(); car.intro(); }}Copy the code

Now, the client code is concise. Because the Builder pattern follows the dependency reversal principle, we can demonstrate code flexibility by simply replacing the client Builder or Director with a different interface implementation class (polymorphic).

The UML class diagram is shown as follows: