设计模式-建造者模式(Builder)

简介:

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


结构图:


优点:

  1. 使得创建代码和表示代码分离,建造者隐藏了该产品是如何组装的,所以若需要改变一个产品内部的表示,只需要再定义一个具体的建造者就可以了;
  2. 便于控制细节风险。

缺点:

  1. 产品必须有共同点,范围有限制;
  2. 若内部变化复杂,会有很多建造者类。

应用场景:

  1. 主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但内部的构建通常面临这复杂的变化;
  2. 当创建复杂对象的算法应该独立于该对象的组成部分以及装配方式时;
  3. 需要生产的产品对象的属性相互依赖,需要指定其生成顺序时。

注意事项:

与工厂模式相比,更加关注与零配件的装配顺序。


示例:

 1.结构类图的实现

Product类,产品类,由多个部件组成

    /// <summary>
    /// 产品类
    /// </summary>
    public class Product
    {
        List<string> parts = new List<string>();
        /// <summary>
        /// 添加产品部件
        /// </summary>
        /// <param name="part"></param>
        public void AddPart(string part)
        {
            parts.Add(part);
        }
        /// <summary>
        /// 列举所有产品部件
        /// </summary>
        public void Show()
        {
            Console.WriteLine("产品创建-----------");
            parts.ForEach(x => Console.WriteLine(x));
        }
    }

Builder类,抽象建造者类,确定产品是由两个部件PartA和PartB组成,并声明一个得到产品建造后的结果的方法GetResult()

    /// <summary>
    /// 抽象建造者类
    /// </summary>
    public abstract class Builder
    {
        /// <summary>
        /// 部件A
        /// </summary>
        public abstract void BuildPartA();
        /// <summary>
        /// 部件B
        /// </summary>
        public abstract void BuildPartB();
        /// <summary>
        /// 获取产品
        /// </summary>
        /// <returns>具体产品</returns>
        public abstract Product GetResult();
    }

ConcreteBuilder类,具体的建造者类

    public class ConcreteBuilder1 : Builder
    {
        private Product product = new Product();
        public override void BuildPartA()
        {
            product.AddPart("部件A");
        }

        public override void BuildPartB()
        {
            product.AddPart("部件B");
        }

        public override Product GetResult()
        {
            return product;
        }
    }

    public class ConcreteBuilder2 : Builder
    {
        private Product product = new Product();
        public override void BuildPartA()
        {
            product.AddPart("部件X");
        }

        public override void BuildPartB()
        {
            product.AddPart("部件Y");
        }

        public override Product GetResult()
        {
            return product;
        }
     }

Director类,指挥者类,规范产品部件生成的顺序

    /// <summary>
    /// 指挥者类
    /// </summary>
    public class Director
    {
        public void Construct(Builder builder)
        {
            builder.BuildPartA();
            builder.BuildPartB();
        }
    }

客户端

     Director director = new Director();
     ConcreteBuilder1 builder1 = new ConcreteBuilder1();
     director.Construct(builder1);
     Product p1 = builder1.GetResult();
     p1.Show();

     ConcreteBuilder2 builder2 = new ConcreteBuilder2();
     director.Construct(builder2);
     Product p2 = builder2.GetResult();
     p2.Show();

结果

2.建造者模式之西安美食

去西安必须要吃的就是凉皮,肉夹馍,羊肉泡馍...,这些美食会以套餐的形成展示给我们,不同的套餐就是【Product】,一道道美食就是组成【Product】的部件;不同的组合方式就是【Builder】,厨师【Director】将他们搭配起来。

套餐

    /// <summary>
    /// 套餐
    /// </summary>
    public class Meal
    {
        List<string> parts = new List<string>();
        public void AddPart(string part)
        {
            parts.Add(part);
        }

        public void Show()
        {
            Console.WriteLine("您的套餐齐了:");
            parts.ForEach(x => Console.Write(x + " "));
            Console.WriteLine("\n**************");
        }
    }

套餐创建的抽象类

    /// <summary>
    /// 创建套餐
    /// </summary>
    public abstract class BuildMeal
    {
        protected Meal meal = new Meal();
        public abstract void BuildePartA();
        public abstract void BuildePartB();
        public abstract void BuildePartC();
        public Meal GetMeal()
        {
            return meal;
        }
    }

具体套餐的创建

    /// <summary>
    /// 经典套餐
    /// </summary>
    public class BuildClassicalMeal : BuildMeal
    {
        public override void BuildePartA()
        {
            meal.AddPart("肉夹馍");
        }

        public override void BuildePartB()
        {
            meal.AddPart("凉皮");
        }

        public override void BuildePartC()
        {
            meal.AddPart("冰峰");
        }
    }
    /// <summary>
    /// 豪华套餐
    /// </summary>
    public class BuildLuxuriousMeal : BuildMeal
    {
        public override void BuildePartA()
        {
            meal.AddPart("羊肉泡馍");
        }

        public override void BuildePartB()
        {
            meal.AddPart("糖蒜");
        }

        public override void BuildePartC()
        {
            meal.AddPart("黑米粥");
        }
    }

厨师装配

    /// <summary>
    /// 厨师
    /// </summary>
    public class Chef
    {
        /// <summary>
        /// 生成套餐的过程
        /// </summary>
        /// <param name="buildMeal"></param>
        public void GiveMeal(BuildMeal buildMeal)
        {
            buildMeal.BuildePartA();
            buildMeal.BuildePartB();
            buildMeal.BuildePartC();
        }
    }

客户端

    Chef chef = new Chef();
    BuildClassicalMeal buildClassical = new BuildClassicalMeal();
    chef.GiveMeal(buildClassical);
    Meal classicalMeal = buildClassical.GetMeal();
    classicalMeal.Show();
    
    BuildLuxuriousMeal buildLuxurious = new BuildLuxuriousMeal();
    chef.GiveMeal(buildLuxurious);
    Meal luxuriousMeal = buildLuxurious.GetMeal();
    luxuriousMeal.Show();

结果

请 多多指教~(看过记得到西安去品尝哟)

posted @ 2018-06-05 19:49  稻草堆上打着滚儿  阅读(520)  评论(0编辑  收藏  举报