设计模式(十四)之建造者模式

发布时间:2019-07-30 09:18:07 阅读:22

    建造者模式(Builder):

    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示

     

    使用角色:

    Builder(抽象建造者)

    ConcreteBuilder(具体建造者,可能有多个)

    Product(产品)

    Director(指挥者)

     

    建造者UML图:

    121212121212121221212.png

     

    建造者模式精髓:建造者模式使得建造代码与表示代码的分离,可以使客户端不必知道产品内部组成的细节,从而降低了客户端与具体产品之间的耦合度。

     

    建造者模式实现:

    我去饭店吃饭,饭店的招牌菜是西红柿炒鸡蛋,饭店很火,有多位厨师(建造者类),为了避免,多个厨师做出多种口味的菜,店家将制作时需要添加的材料做成了一个秘制菜谱(建造类),厨师只要按照菜谱做,菜谱上详细的说明了材料的放置顺序,必须是先放西红柿,再放鸡蛋,再放糖,口味就不会有偏差。我去饭店吃饭,我不需要关心你的菜是怎么做出来的,我只需要告诉服务员(指挥者类)我要吃西红柿炒鸡蛋(产品),他把菜给我端上来就行了。

     

    上代码:

    产品类:Product.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace Builder
    {
        /// <summary>
        /// 产品类
        /// </summary>
        public class Product
        {
            /// <summary>
            /// 产品列表
            /// </summary>
            public List<string> productList = new List<string>();
            /// <summary>
            /// 添加
            /// </summary>
            /// <param name="name"></param>
            public void add(string name)
            {
                productList.Add(name);
            }
            /// <summary>
            /// 展示
            /// </summary>
            public void show()
            {
                for (int i = 0; i < productList.Count; i++)
                {
                    Console.WriteLine(productList[i]);
                }
            }
        }
    }

     

    建造者类:Builder.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace Builder
    {
        /// <summary>
        /// 建造者类
        /// </summary>
        public abstract class Builder
        {
            /// <summary>
            /// 放西红柿
            /// </summary>
            public abstract void cai();
     
            /// <summary>
            /// 放糖
            /// </summary>
            public abstract void tang();
     
            /// <summary>
            /// 放鸡蛋
            /// </summary>
            public abstract void dan();
     
            /// <summary>
            /// 返回产品
            /// </summary>
            /// <returns></returns>
            public abstract Product GetResult();
        }
    }

     

    具体建造者类:BuilderOne.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace Builder
    {
        class BuilderOne:Builder
        {
            /// <summary>
            /// 建造者二
            /// </summary>
            public Product pro = new Product();
     
            /// <summary>
            /// 放西红柿
            /// </summary>
            public override void cai()
            {
                pro.productList.Add("大厨放西红柿");
            }
     
            /// <summary>
            /// 放糖
            /// </summary>
            public override void tang()
            {
                pro.productList.Add("大厨放糖");
            }
     
            /// <summary>
            /// 放鸡蛋
            /// </summary>
            public override void dan()
            {
                pro.productList.Add("大厨放鸡蛋");
            }
     
     
            public override Product GetResult()
            {
                return pro;
            }
     
        }
    }

     

    具体建造者类2:BuilderTwo.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace Builder
    {
        class BuilderTwo:Builder
        {
            /// <summary>
            /// 建造者一
            /// </summary>
            public Product pro = new Product();
            /// <summary>
            /// 放西红柿
            /// </summary>
            public override void cai()
            {
                pro.productList.Add("二厨放西红柿");
            }
     
            /// <summary>
            /// 放糖
            /// </summary>
            public override void tang()
            {
                pro.productList.Add("二厨放糖");
            }
     
            /// <summary>
            /// 放鸡蛋
            /// </summary>
            public override void dan()
            {
                pro.productList.Add("二厨放鸡蛋");
            }
     
     
            public override Product GetResult()
            {
                return pro;
            }
        }
    }

     

    指挥者类:负责指挥建造过程Director.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace Builder
    {
        /// <summary>
        /// 建造类
        /// </summary>
        public class Director
        {
            /// <summary>
            /// 指挥建造过程(不向客人展示建造过程)
            /// </summary>
            /// <param name="build"></param>
            public void waiter(Builder build)
            {
                build.cai();
                build.dan();
                build.tang();
            }
        }
    }

     

    客户端:Program.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace Builder
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 两个客人同时点了西红柿炒鸡蛋,大厨和二厨依次接单做
     
                // 大厨
                Builder build_one = new BuilderOne();
                // 二厨
                Builder build_two = new BuilderTwo();
                // 指挥者类
                Director dir = new Director();
     
                // 指挥大厨做饭
                dir.waiter(build_one);
                // 做完饭
                Product p1 = build_one.GetResult();
                // 上菜
                p1.show();
     
                Console.WriteLine("大厨上菜");
                Console.WriteLine("----------------------------------------");
                // 指挥二厨做饭
                dir.waiter(build_two);
                // 做完饭
                Product p2 = build_two.GetResult();
                // 上菜
                p2.show();
                Console.WriteLine("二厨上菜");
                Console.ReadLine();
            }
        }
    }

    结果如下图所示:

    1212121212.png

     

    建造者模式应用分析

    建造者模式适用情形:

    1.      需要生成的产品对象有复杂的内部结构

    2.      需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序

    3.      在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到

     

    建造者模式特点:

    1.      建造者模式的使用使得产品的内部表对象可以独立地变化。使用建造者模式可以使客户不必知道产品内部组成的细节

    2.      每一个Builder都相对独立,而与其他Builder无关

    3.      可使对构造过程更加精细控制

    4.      将构建代码和表示代码分开

    5.      建造者模式的缺点在于难于应付分步骤构建算法的需求变动

     

    有好的建议,请在下方输入你的评论。


资源下载:

上一篇:C#委托

下一篇:​机器人技术基础