Builder pattern
This blog will introduce the builder mode. The builder mode is a more complex creative design mode. Compared with the factory mode, the builder mode pays more attention to the assembly process of an object. Generally, the builder mode is suitable for the creation of complex objects and is often used in conjunction with the factory mode.
pattern classification
Create a design pattern.
Causes of mode
In actual software development, there will be a complex object requirement. Complex object generally refers to the object composed of several sub objects by using the principle of combination and reuse, and there may be a certain order between the sub objects. At this time, if we want to create this object, we need to create its sub objects one by one. If you understand the abstract factory well, you will find that the requirements here can be solved through the abstract factory. As long as we replace a product family with sub objects of complex objects and add a commander class between the client and the factory, this basically constitutes the creator mode we want to talk about today.
Source of model inspiration
For example, in the production of vehicles in the real world, a car is not directly produced. We need Mr. to produce its four wheels, steering wheel, engine and so on, and finally assemble it through the factory assembly line. Similarly, the builder pattern separates the assembly of sub objects from their representation, and focuses on how to create a complex object with multiple sub objects step by step. Just like the vehicle assembly line in real life.
Pattern class diagram
It can be seen from the figure that the builder mode consists of four roles:
Builder (Abstract builder):
Specify an abstract interface for each component that creates a product object. Two methods are generally provided in this interface or class. The first is the creation method of each component, and the other is the object return method, which is used to return the constructed object.
ConcreteBuilder (specific builder):
The concrete builder implements or inherits the abstract builder to realize the creation method and object return method of each component.
Product:
A complex object that is constructed and contains multiple components.
Director:
The commanders are responsible for arranging the order of complex objects. There is a correlation between the commanders and the builders. In the Construct method, the builder can build the components to complete the construction task and return to the completed object. We need to specify which builder to use first. Generally, users only need to interact with the commander class.
Classic code implementation
The creation process of game characters is simulated here:
Builder:
namespace Builder.Builder.Example { public interface IActorBuilder { Actor Product { get; set; } void CreateName(); void CreateAge(); void CreateSex(); Actor ReturnResult(); } }
ConcreteBuilder:
namespace Builder.Builder.Example { public class AngleBuilder : IActorBuilder { private Actor _product; public Actor Product { get { if (_product == null) { _product = new Actor(); } return _product; } set => _product = value; } public void CreateName() { Product.Name = "angel"; } public void CreateAge() { Product.Age = 20; } public void CreateSex() { Product.Sex = "female"; } public Actor ReturnResult() { return Product; } } }
Product:
namespace Builder.Builder.Example { public class Actor { public string Name { get; set; } public int Age { get; set; } public string Sex { get; set; } } }
Director:
namespace Builder.Builder.Example { public class ActorDirector { private IActorBuilder _builder; public void SetBuilder(IActorBuilder builder) { _builder = builder; } public Actor Construct() { _builder.CreateAge(); _builder.CreateName(); _builder.CreateSex(); return _builder.ReturnResult(); } } }
Program:
using System; using Builder.Builder.Example; namespace Builder { internal class Program { public static void Main(string[] args) { ActorDirector ad = new ActorDirector(); ad.SetBuilder(new AngleBuilder()); Actor actor = ad.Construct(); Console.WriteLine($"The name is:{actor.Name}"); Console.WriteLine($"Age:{actor.Age}"); Console.WriteLine($"Gender:{actor.Sex}"); } } }
Optimization of builder mode
Director omitted
The Director of the Director class is an important part of the Builder mode. It is responsible for directing the Builder to build the sequence of various components and returning the complete product object to the user. Sometimes, in order to simplify the system, we can omit the writing of the Director and integrate the Director related code, that is, the Construct method, into the Builder. In this way, the user can directly call the relevant methods of the Builder.
Hook method introduction
The introduction of hook method is to accurately control the production process of components. What is the hook method? Hook method is usually a bool return value method, which is declared in the builder class and used in the commander class to judge whether to build a component.
Builder modification:
namespace Builder.Builder.Example { public class AngleBuilder : IActorBuilder { //... Previous code //Assuming that the role has no name, this method is declared as a virtual method in the parent class, because it is not necessarily used public override bool HasName() { return false; } } }
Commander modification:
For convenience of observation, unimportant code is commented out here.
namespace Builder.Builder.Example { public class ActorDirector { /*private IActorBuilder _builder; public void SetBuilder(IActorBuilder builder) { _builder = builder; }*/ public Actor Construct() { //_builder.CreateAge(); if(!_builder.HasName()) _builder.CreateName(); //_builder.CreateSex(); return _builder.ReturnResult(); } } }
Summary of builder model
Advantages of builder mode:
- In the builder mode, users do not need to know the details of the internal composition of the product, and decouple the product itself from the product creation process, so that the same creation process can create different objects.
- Each specific builder is independent of each other, so we can easily add new builders, and users can use different builders to obtain different product objects.
- Users can more accurately control the product creation process.
Disadvantages of builder mode:
- The premise of builder's use is that there is a high similarity between various products. If the difference is too large, it is not suitable to use builder's mode. However, if the product has a product family, this problem can be solved through the combination of factory mode and builder mode.
, decouple the product itself from the product creation process, so that the same creation process can create different objects.
2. Each specific builder is independent of each other, so we can easily add new builders, and users can use different builders to obtain different product objects.
3. Users can more accurately control the product creation process.