Builder Pattern

http://www.codeproject.com/Articles/42415/Builder-Design-Pattern

In Elizabeth's day care center, the teacher helps the kids to build all kinds of toys to develop their creative skills. One of Elizabeth's favorite activities is to make animals with play-dough.

在伊丽莎白所在的托儿所,老师帮助孩子们,构造各种各样玩具来开发孩子们的创造能力。伊丽莎白最喜欢的一个活动是用橡皮泥来做动物。

A set of molds is the tool that Elizabeth always uses to create her favorite cool animals.

一套模具,是伊丽莎白经常用来创造她最喜欢最酷的动物的工具。

One mold tool set includes five parts, including the head, body, arm, leg, and tail. Whenever Elizabeth wants to build an animal, she will use one set of each tools to make a head, body , leg, arm, and tail for that animal, and then assembles them with glue to build an animal. 

一套模具包含五个部分,包括头、身体、手臂、腿、尾巴。无论何时,当伊丽莎白想要构造一个动物的时候,她就会使用那个动物模具中分别来做 头、身体、腿、手臂以及尾巴。最后用胶水把它们粘起来,组成一个动物。

There are many types of animal mold tool sets that the kids can choose from.

这里有许多类型的动物模具让孩子们可以进行选择。

For example: if Elizabeth wants to make a monkey, then she will pick the set of monkey molds to start.

例如:如果伊丽莎白想要做一个猴子,那么她会挑选出猴子模具做一下步骤:

  • Step 1. Make monkey head.
  • Step 2. Make monkey body.
  • Step 3. Make monkey leg.
  • Step 4. Make monkey arm.
  • Step 5. Make monkey tail.

Once all the five parts are finished, then Elizabeth will glue them all together and decorate it to have a monkey done as a finished product.

一旦五个部分完成了,那么伊丽莎白就会用胶水把它们粘起来,最后装饰一下它,就可以得到一个完成的作品,一个猴子。

Most likely, she will give it to me or her mom as a gift when we pick her (she will not give us the monkey if the monkey is not decorated, since it will not be looking good at all then).

在我们去托儿所接她的时候,大多数情况下,她会把这个猴子作为礼物送给我或者她的妈妈。(在猴子没有装饰之前,它不会把猴子给我们,因为没有装饰前,它一点都不好看)

When she wants to make a kitten, she follows the same steps with the set of Kitten molds.

当她想要做一个小猫的时候,她使用小猫的模具,按照相同的步骤来处理。

In the above scenario, an Builder Design Pattern is perfectly used by Elizabeth in her daily fun activities.

在上述情景中,伊丽莎白在她有趣的日常活动中完美地使用了创建者模式

Introduction

The Builder Design Pattern helps us to slice the operations of building an object.

创建者模式帮助我们分解创建一个对象的操作

It also enforces a process to create an object as a finished product.

它会确保创建一个对象作为完成的产品是按照一个程序来执行的。

That means an object has to be massaged by some instructed steps before it is ready and can be used by others.     

instructed 受教育的;得到指示的

The massage process could apply any restrictions or business rules for a complete building procedure (or a procedure we follow to make an object that is considered as a ready to use object).

restriction 限制;约束;束缚

 procedure  程序,手续;步骤

For instance, to compose an email, you can't leave the To and Subject fields blank before you can send it.

compose  构成;写作;使平静;排…的版

In other words, an email object will be considered as an uncompleted email object (a common business rule for email) if those two fields are not filled.

It has to be built (filled) before we can send it out.

This article introduces an implementation of how we use the Builder Design Pattern for Elizabeth's fun activity.

Implementation Code

Builder Objects

AnimalBuilder

The AnimalBuilder class is a base abstract class. It contains all the building methods to construct a general product (Animal).A public Animal object is also declared here to implement the concept (GetResult) of returning a ready to use object. Well, it can also be a private product object; in that case, a GetResult method has to be introduced to return a ready to use product.

public abstract class AnimalBuilder
    {
        public Animal animal;

        public abstract void BulidHead();
        public abstract void BulidBody();
        public abstract void BulidArm();
        public abstract void BulidLeg();
        public abstract void BulidTail();
    }

MonkeyBuilder

The MonkeyBuilder class is a child class of AnimalBuilder. It provides the details of each building method for a Monkey. In this class, we apply all the rules to make our product (Monkey) a ready to use object (decorated monkey). In the constructor, we also initialize the Animal object (aAnimal) to be a Monkey object.

 class MonkeyBuilder:AnimalBuilder
    {
        public MonkeyBuilder()
        {
            animal = new Monkey();
        }

        public override void BulidHead()
        {
            animal.Head = "Moneky's Head has been built";
        }

        public override void BulidBody()
        {
            animal.Body = "Moneky's Body has been built";
        }

        public override void BulidArm()
        {
            animal.Arm = "Moneky's Arm has been built";
        }

        public override void BulidLeg()
        {
            animal.Leg = "Moneky's Leg has been built";
        }

        public override void BulidTail()
        {
            animal.Tail = "Moneky's Tail has been built";
        }
    }

KittenBuilder

    /// <summary>
    /// Same as MonkeyBuilder, the KittenBuilder class will implement the details for building a Kitten object.
    /// </summary>
    class KittenBuilder : AnimalBuilder
    {
        public KittenBuilder()
        {
            animal = new Kitten();
        }

        public override void BulidHead()
        {
            animal.Head = "Kitten's Head has been built";
        }

        public override void BulidBody()
        {
            animal.Body = "Kitten's Body has been built";
        }

        public override void BulidArm()
        {
            animal.Arm = "Kitten's Arm has been built";
        }

        public override void BulidLeg()
        {
            animal.Leg = "Kitten's Leg has been built";
        }

        public override void BulidTail()
        {
            animal.Tail = "Kitten's Tail has been built";
        }
    }

Product Object

Animal

    /// <summary>
    /// The Animal class is an abstract base class that holds the basic information for a product. It helps us build multiple products.
    /// </summary>
    public abstract class Animal
    {
        public string Head { get; set; }
        public string Body { get; set; }
        public string Arm { get; set; }
        public string Leg { get; set; }
        public string Tail { get; set; }

        //helper method for demo the Polymorphism, so we can 
        //easily tell what type object it is from client.
        public abstract void Eat();

        //helper method for demo the result from client
        public void ShowMe()
        {
            Console.WriteLine(Head);
            Console.WriteLine(Body);
            Console.WriteLine(Arm);
            Console.WriteLine(Leg);
            Console.WriteLine(Tail);
            Eat();
        }
    }

Monkey Class

    /// <summary>
    /// The Monkey class is a concrete product class that will be built from a MonkeyBuilder.
    /// </summary>
    public class Monkey : Animal
    {
        //helper method to show monkey's property for demo purpose
        public override void Eat()
        {
            Console.WriteLine("Since I am Monkey, I like to eat banana");
        }
    }

Kitten Class

    /// <summary>
    /// Same as the Monkey class, a concrete product class that will be built from a Kittenbuilder.
    /// </summary>
    public class Kitten : Animal
    {
        public override void Eat()
        {
            Console.WriteLine("Since I am Kitten, I like to eat kitten food");
        }
    }

Constructor Object

Kid class

class Kid
    {
        public string Name { get; set; }

        //construct process to build an animal object, 
        //after this process completed, a object 
        //will be consider as a ready to use object.
        public void MakeAnimal(AnimalBuilder animalBuilder)
        {
            animalBuilder.BulidHead();
            animalBuilder.BulidBody();
            animalBuilder.BulidArm();
            animalBuilder.BulidLeg();
            animalBuilder.BulidTail();
        }
    }

Client App

    /// <summary>
    /// From the client side, I create a Kid (constructor object) named Elizabeth. 
    /// Elizabeth will use the monkey mold tool set to make a monkey, and she also uses the kitten mold toolkit to make a kitten. 
    /// From the client, you will see I can directly use builderA.animal as a ready to use object after it's been built (because it has the public property in the base AnimalBuilder class). 
    /// It might be a private field which has a public method to access it as well.
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            AnimalBuilder animalBuilder;
            Kid kid = new Kid
            {
                Name = "Elizabeth"
            };

            Console.WriteLine("{0} start making a monkey", kid.Name);
            animalBuilder = new MonkeyBuilder();
            kid.MakeAnimal(animalBuilder);
            animalBuilder.animal.ShowMe();

            Console.WriteLine();

            Console.WriteLine("{0} start making a kitten", kid.Name);
            animalBuilder = new KittenBuilder();
            kid.MakeAnimal(animalBuilder);
            animalBuilder.animal.ShowMe();

            Console.ReadKey();

        }
    }

once we start our client app, you will see a Monkey and a Kitten are both created. All the corresponding fields are completed to get ready to use objects. Cool!

Conclusion

In this article, I demonstrated how we can use the Builder Pattern to achieve an implementation to construct objects as ready to use based on some requirements.

I have also written another article for the Visitor Design Pattern for Elizabeth's day care center: Visitor_Design_Pattern.aspx.

 

Update: I recently came across an even better example (imo). Checkout the JobBuilder and TriggerBuilder implementations in the Quartz scheduler package:

https://github.com/quartznet/quartznet/blob/master/src/Quartz/TriggerBuilder.cs

https://github.com/quartznet/quartznet/blob/master/src/Quartz/JobBuilder.cs

Builder Pattern VS Factory Method

 https://blog.csdn.net/monkeyd5/article/details/73478940

工厂模式用于处理 如何获取实例对象问题,建造者模式用于处理 如何建造实例对象 问题。

https://www.cnblogs.com/ChinaHook/p/7471470.html

 工厂方法模式和建造者模式都属于对象创建类模式,都用来创建类的对象。但它们之间的区别还是比较明显的。

  ● 意图不同

  在工厂方法模式里,我们关注的是一个产品整体,如超人整体,无须关心产品的各部分是如何创建出来的;但在建造者模式中,一个具体产品的产生是依赖各个部件的产生以及装配顺序,它关注的是“由零件一步一步地组装出产品对象”。简单地说,工厂模式是一个对象创建的粗线条应用,建造者模式则是通过细线条勾勒出一个复杂对象,关注的是产品组成部分的创建过程。

  ● 产品的复杂度不同

  工厂方法模式创建的产品一般都是单一性质产品,如成年超人,都是一个模样,而建造者模式创建的则是一个复合产品,它由各个部件复合而成,部件不同产品对象当然不同。这不是说工厂方法模式创建的对象简单,而是指它们的粒度大小不同。一般来说,工厂方法模式的对象粒度比较粗,建造者模式的产品对象粒度比较细。
  两者的区别有了,那在具体的应用中,我们该如何选择呢?是用工厂方法模式来创建对象,还是用建造者模式来创建对象,这完全取决于我们在做系统设计时的意图,如果需要详细关注一个产品部件的生产、安装步骤,则选择建造者,否则选择工厂方法模式。

建造者模式

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

介绍

意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示

主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

何时使用:一些基本部件不会变,而其组合经常变化的时候。

如何解决:将变与不变分离开。

关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。

应用实例: 1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。

优点: 1、建造者独立,易扩展。 2、便于控制细节风险。

缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。

使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

注意事项:与工厂方法模式的区别是:建造者模式更加关注与零件装配的顺序。

原文地址:https://www.cnblogs.com/chucklu/p/4534254.html