Let's start with an example, let's say we want to make CarA, CarB
public class CarA { public void makeWheels(){ System.out.println("Manufacture CarA Wheel of"); } public void makeCarBody(){ System.out.println("Manufacturing Cars CarA body"); } public void sprayPaint(){ System.out.println("to CarA Spray paint"); } public void build(){ makeWheels(); makeCarBody(); sprayPaint(); } }
public class CarB { public void makeWheels(){ System.out.println("Manufacture CarB Wheel of"); } public void makeCarBody(){ System.out.println("Manufacturing Cars CarB body"); } public void sprayPaint(){ System.out.println("to CarB Spray paint"); } public void build(){ makeWheels(); makeCarBody(); sprayPaint(); } }
public class Test { public static void main(String[] args) { CarA carA = new CarA(); carA.build(); CarB carB = new CarB(); carB.build(); } }
Result:
Manufacturing wheels for CarA
Manufacturing CarA Body
Paint CarA
Wheels for making CarB
Manufacturing CarB Body
Paint CarB
From the example above, we can see that CarA and CarB have the same construction process, they all need to make wheels, body and spray paint. This process is "stable", but the details of implementation are different. Assuming we need to add a new CarC class now, we need to re-implement the above process again.There is a possibility of errors in the process that occurs (CarC was created without a way to create parts) and the client needs to know the process of creating the product (resulting in high coupling), so we can use the Builder mode where the user only needs to specify the type of construction and not the details.
Builder mode: Separates the construction of a complex object from its representation so that the same construction process can create different representations.Let's look at an example in Builder mode
Automotive class, consisting of several parts
//Product Class public class Car { List<String> list = new ArrayList<>(); //Add to Car Parts public void build(String string){ list.add(string); } //Show all product parts public void show(){ for(String string : list){ System.out.println(string); } } }
Builder interface, which defines that a car consists of three parts and a way to show it.
//Builder Interface, defining the steps to make a car public interface Builder { void makeWheels(); void makeCarBody(); void sprayPaint(); //Definition Display Car Method Car showCar(); }
//Specific construction classes A public class BuildCarA implements Builder { Car car = new Car(); @Override public void makeWheels() { car.build("Manufacture CarA Wheel of"); } @Override public void makeCarBody() { car.build("Manufacturing Cars CarA body"); } @Override public void sprayPaint() { car.build("to CarA Spray paint"); } @Override public Car showCar() { return car; } }
//Specific construction classes B public class BuildCarB implements Builder { Car car = new Car(); @Override public void makeWheels() { car.build("Manufacture CarB Wheel of"); } @Override public void makeCarBody() { car.build("Manufacturing Cars CarB body"); } @Override public void sprayPaint() { car.build("to CarB Spray paint"); } @Override public Car showCar() { return car; } }
Director class, Commander class, through which clients build products without knowing the details.
//The Commander class is used to direct the construction process public class Director { public void Construct(Builder builder){ builder.makeWheels(); builder.makeCarBody(); builder.sprayPaint(); } }
Test Class
public class Test2 { public static void main(String[] args) { Director director = new Director(); Builder buildCarA = new BuildCarA(); Builder buildCarB = new BuildCarB(); //Build products by commander director.Construct(buildCarA); Car carA = buildCarA.showCar(); carA.show(); director.Construct(buildCarB); Car carB = buildCarB.showCar(); carB.show(); } }
Test results:
Manufacturing wheels for CarA
Manufacturing CarA Body
Paint CarA
Wheels for making CarB
Manufacturing CarB Body
Paint CarB
Summary: For complex creation and client-controlled creation (see Test for this design issue), repetitive operations are used each time a client creates a product (see Test for this design issue), and steps may be missing (avoided through Builder interface in Builder mode), or product objectsWhen it is changeable (see BuildCarA, BuildCarB,), we can use the Builder mode.This pattern separates the client from the product and creates stable internal building methods but implements objects with different details.