The builder of design pattern

Posted by $0.05$ on Thu, 30 Dec 2021 01:58:06 +0100

Builder mode

Meaning: generator mode is a creation mode, which enables you to create complex objects step by step. You can use the same creation code to generate objects of different types and forms.

Looking at the picture, we can well understand that the picture is the assembly line mode in the factory. The builder is like the whole assembly line. The workers at each assembly point on the assembly line can assemble and integrate product parts into a complete product.

The object construction code is extracted from the specific product class and placed in a separate object called generator.

It allows you to create complex objects step by step and does not allow other objects to access the product being created.

The specific content produced by using the same materials and different assemblies is the final embodiment of the builder's mode.

Separating a complex build from its representation allows the same build process to create different representations.

Generator pattern structure

  1. The builder interface declares a product construction step common to all types of builders.

  2. Concrete builders provide different implementations of the construction process, and concrete builders can also construct products that do not follow the general interface.

  3. Products are the final generated objects. Products constructed by different generators do not need the same kind of hierarchy or interface of data.

  4. The director class defines the order in which the construction steps are called, so that specific product configurations can be created and reused.

The main problem of builder mode is that in software system, sometimes we are faced with the creation of a complex object, which is usually composed of sub objects of each part with a certain process; Due to the change of requirements, each part of this complex object often faces significant changes, but the process of combining them is relatively stable.

Demo presentation

Here I will take the delivery process of express logistics company as an example. I hope you can have a good understanding of the builder model.

Xiao A goes to the logistics company to deliver goods. The goods in his hand have to be sent to three different places. The logistics company will have different charging standards according to different regions. But for Xiao A, he doesn't need to care about those. He just needs to give three things to the receiver and fill in the receiving address of their goods. The receiver gives A quotation by calculating the charges at different receiving addresses and tells Xiao A how much to pay. Xiao A only needs to pay.

Here, the charges are different in different regions, and the business of giving quotation can be realized by using the builder mode we just learned. Due to the different transportation routes, delivery methods and packaging methods in different regions, the charging standards are also different.

Class structure description

  • Shipment goods category (basic attribute)

  • Shipment abstract class (generator)

  • Charging classes in different regions (specific generator, implementation class of generator)

  • Control class of delivery (supervisor)

    /// <summary>
    ///Logistics company delivery base class
    ///Transportation mode, packaging style and transportation type
    /// </summary>
    public class Matter
    {
        /// <summary>
        ///Packaging style
        /// </summary>
       public string PackStyle{get;set;}
        /// <summary>
        ///Mode of transport
        /// </summary>
       public string TransportWay { get; set; }
        /// <summary>
        ///Is there any tax
        /// </summary>
       public string IsHaveTax { get; set; }
        /// <summary>
        ///Total amount
        /// </summary>
        /// <returns></returns>
       public double Money { get; set; }
        /// <summary>
        ///Description information
        /// </summary>
       public string DescriptionInfo { get; set; }
    }
 /// <summary>
    ///Delivery implementation class: Abstract builder
    /// </summary>
    public abstract class SendModelBuilder
    {
        protected Matter matter = new Matter();

        public abstract void BuilderPackStyle();

        public abstract void BuilderTransportWay();

        public abstract void BuilderIsHaveTax();

        public abstract void BuilderMoney();

        public abstract void BuilderDescriptionInfo();

        /// <summary>
        ///Returns a complete shipping implementation class
        /// </summary>
        /// <returns></returns>
        public Matter CreateMatter()
        {
            return matter;
        }
    }
     /// <summary>
    ///Founder of Japan
    /// </summary>
    public class RiBenBuilder : SendModelBuilder
    {
        public override void BuilderPackStyle()
        {
            matter.PackStyle = "Wooden box packaging";
        }

        public override void BuilderTransportWay()
        {
            matter.TransportWay = "waterway";
        }

        public override void BuilderIsHaveTax()
        {
            matter.IsHaveTax = "have";
        }

        public override void BuilderMoney()
        {
            matter.Money = 1000;
        }

        public override void BuilderDescriptionInfo()
        {
            matter.DescriptionInfo = "The transportation is by water. The goods are packed in wooden boxes, with taxes and fees, and the amount is 1000 yuan";
        }
    }
    /// <summary>
    ///Founder of Beijing
    /// </summary>
    public class BeiJingBuilder : SendModelBuilder
    {
        public override void BuilderPackStyle()
        {
            matter.PackStyle = "Carton";
        }

        public override void BuilderTransportWay()
        {
            matter.TransportWay = "land transportation";
        }

        public override void BuilderIsHaveTax()
        {
            matter.IsHaveTax = "have";
        }

        public override void BuilderMoney()
        {
            matter.Money = 50;
        }

        public override void BuilderDescriptionInfo()
        {
            matter.DescriptionInfo = "The transportation is land transportation, and the goods are packed in cartons without tax. The amount is 50 yuan";
        }
    }
    /// <summary>
    ///Founder of India
    /// </summary>
    public class YinDuBuilder : SendModelBuilder
    {
        public override void BuilderPackStyle()
        {
            matter.PackStyle = "Carton packaging";           
        }

        public override void BuilderTransportWay()
        {
            matter.TransportWay = "air transport";
        }

        public override void BuilderIsHaveTax()
        {
            matter.IsHaveTax = "have";
        }

        public override void BuilderMoney()
        {
            matter.Money = 3000;
        }

        public override void BuilderDescriptionInfo()
        {
            matter.DescriptionInfo = "The transportation is by air. The goods are packed in cartons. There are taxes and fees, and the amount is 3000 yuan";
        }
    }
    /// <summary>
    ///Rapid logistics delivery creation controller
    /// </summary>
    public class JiSuWuLiuController
    {
        public Matter SendModel(SendModelBuilder builder) 
        {
            builder.BuilderPackStyle();
            builder.BuilderTransportWay();
            builder.BuilderIsHaveTax();
            builder.BuilderMoney();
            builder.BuilderDescriptionInfo();
            return builder.CreateMatter();
        }
    }

The above list is the specific code implementation of each class. The following is the test. At present, take the delivery in Beijing as an example.

    class Program
    {
        static void Main(string[] args)
        {
            SendModelBuilder smb = new BeiJingBuilder();
            JiSuWuLiuController director = new JiSuWuLiuController();
            Matter matter = director.SendModel(smb);
            Console.WriteLine("Package type:"+matter.PackStyle);
            Console.WriteLine("type of shipping:" + matter.TransportWay);
            Console.WriteLine("Whether there are taxes:" + matter.IsHaveTax);
            Console.WriteLine("Freight:" + matter.Money);
            Console.WriteLine("Information:"+matter.DescriptionInfo);
            Console.ReadKey();
        }
    }

test result

It can be seen that when we implement, we just declare and call the creator of BeiJingBuilder by director, and the specific business is only implemented in BeiJingBuilder class alone. If we want to change to other regions, we just need to change the declaration.

Summary

advantage:

  • The client does not need to know the internal composition details of the product, and separates the product itself from the creation of the product, that is, decoupling, so that different product objects can be created in the same creation process.

  • The specific construction is independent. Adding new builders does not need to modify the original library. The system expansion is convenient and conforms to the opening and closing principle.

  • It is convenient to control the product creation process.

Disadvantages:

  • When there are many products, the code is redundant and the system becomes too large, which increases the understanding difficulty and operation cost of the system.

  • This model is mainly applicable when their products have certain commonalities. If the product independence is too strong and there is no same commonalities, it is not suitable for this model.

Topics: Design Pattern