Builder model

I have been writing framework recently, this series has not been updated for a long time, take time to update ~

An overview of the

Wiki: Builder Pattern: Separates the construction of a complex object from its representation so that the same construction process can create different representations.

To put it bluntly, we take large objects we encounter during development, break them into smaller objects, and then assemble them into larger objects, and hide the construction process from the outside world.

structure

The Builder pattern consists of the following four parts

  • -Blair: You’re an abstract Builder

  • -Serena: ConcreteBuilder

  • Director: commander

  • Production: large products and small products

Class diagram && sequence diagram

(Figure source network)

From the two figures above, you can see the flow of the Builder pattern:

  1. Create a large product builder
  2. Create commander
  3. Pass the builder into the commander object
  4. The director directs the builder to create the object and return it

Take a chestnut

Let’s talk about a car-assembly chestnut that the Internet said was bad,

Let’s say I’m an old driver, but I want to build a car, but the structure of the car is too complicated, so we can split the car…

4 wheels, 1 chassis, 1 driver’s seat…

Okay, to keep things simple, let’s build these three. Let’s build a climbing plow…

So I need a large project builder called CarBuilder:

  
type CarBuilder struct {
	Car *Car
}

func (cb *CarBuilder) GetResult(a) interface{} {
	return cb.Car
}

func (cb *CarBuilder) NewProduct(a) {
	cb.Car = new(Car)
}

func (cb *CarBuilder) BuildWheels(a) {
	cb.Car.Wheels = "build wheels"
}

func (cb *CarBuilder) BuildChassis(a) {
	cb.Car.Chassis = "build chassis"
}

func (cb *CarBuilder) BuildSeat(a) {
	cb.Car.Seat = "build seat"
}
Copy the code

This Builder implements the Builder interface:

  type Builder interface {
  	  NewProduct()       // Create an empty product
	  BuildWheels()      // Build the wheel
	  BuildChassis()     // Build the chassis
	  BuildSeat()        // Build the driver position
	  GetResult() interface{}  // Get the built product
  }
Copy the code

Now pass the specific builder to the commander:

type Director struct {
	builder Builder
}

func (d *Director) SetBuilder(builder Builder) {
	d.builder = builder
}
Copy the code

Now that the commander and builder are ready to build, call the commander’s Generate() method:

func (d *Director) Generate(a) *Car {
	d.builder.NewProduct()
	d.builder.BuildChassis()
	d.builder.BuildSeat()
	d.builder.BuildWheels()
	return d.builder.GetResult().(*Car)
}
Copy the code

Here we have the Car object we need:

   func main(a) {
   	// Create a conductor
   	director := new(Director)
   	// Create the builder
   	builder := new(CarBuilder)
       director.SetBuilder(builder)
   	car := director.Generate()
   	car.Show()
   }
Copy the code

conclusion

The above code, it is an original is not very complex object, to break up, just to the field is set as the most simple of type string, in fact, these fields should be smaller objects, structures, and then also can continue to take these small structures continue to split, broken down into the smallest unit, this is the most clear thinking structure.

I wanted to cite a chestnut applied in the actual project, but the framework has not been finished, so, take a hole first, I will supplement this part after bingo framework is completed.

The code above is stored in a repository called Golang-Design-Patterns

Go web framework bingo, for star, for PR ~