建造者模式

编辑说明

回到首页

概述

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

将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

结构图

代码实现

传统建造者

产品类

    public class Product0
    {
        IList<string> parts = new List<string>();

        public void Add(string part)
        {
            parts.Add(part);
        }

        public void Show()
        {
            Console.WriteLine("\n产品 创建 ----");
            foreach (string part in parts)
            {
                Console.WriteLine(part);
            }
        }
    }

 

建造者类

    public abstract class Builder
    {
        public abstract void BuildPartA();
        public abstract void BuildPartB();
        public abstract Product0 GetResult();
    }
    public class ConcreteBuilder1 : Builder
    {
        private Product0 product = new Product0();
        public override void BuildPartA()
        {
            product.Add("部件A");
        }
        public override void BuildPartB()
        {
            product.Add("部件B");
        }
        public override Product0 GetResult()
        {
            return product;
        }
    }
    public class ConcreteBuilder2 : Builder
    {
        private Product0 product = new Product0();
        public override void BuildPartA()
        {
            product.Add("部件X");
        }
        public override void BuildPartB()
        {
            product.Add("部件Y");
        }
        public override Product0 GetResult()
        {
            return product;
        }
    }

 

指挥类

    public class Director
    {
        public void Construct(Builder builder)
        {
            builder.BuildPartA();
            builder.BuildPartB();
        }
    }

 

客户端

        static void Main(string[] args)
        {
            Director director = new Director();
            Builder b1 = new ConcreteBuilder1();
            Builder b2 = new ConcreteBuilder2();
            director.Construct(b1);
            Product0 p1 = b1.GetResult();
            p1.Show();
            director.Construct(b2);
            Product0 p2 = b2.GetResult();
            p2.Show();
            Console.Read();
        }

 

运行结果

 

 

 

传统建造者改进型

产品类

    public class Product1
    {
        Dictionary<string, string> parts = new Dictionary<string, string>();
        public Product1(Dictionary<string, string> parts)
        {
            this.parts = parts;
        }
        public void Show()
        {
            Console.WriteLine("\n产品 展示 ----");
            foreach (string key in parts.Keys)
            {
                Console.WriteLine(key + ":" + parts[key]);
            }
        }
    }

 

建造者类

    public interface IBuilder
    {
        Product1 Build();
    }
    public class ConcreteIBuilder1 : IBuilder
    {
        Dictionary<string, string> parts = new Dictionary<string, string>();
        public Product1 Build()
        {
            return new Product1(parts);
        }
        public ConcreteIBuilder1 SetPart1(string str)
        {
            parts["part1"] = str;
            return this;
        }
        public ConcreteIBuilder1 SetPart2(string str)
        {
            parts["part2"] = str;
            return this;
        }
        public ConcreteIBuilder1 SetPart3(string str)
        {
            parts["part3"] = str;
            return this;
        }
    }
    public class ConcreteIBuilder2 : IBuilder
    {
        Dictionary<string, string> parts = new Dictionary<string, string>();
        public Product1 Build()
        {
            return new Product1(parts);
        }
        public ConcreteIBuilder2 SetPart11(string str)
        {
            parts["part11"] = str;
            return this;
        }
        public ConcreteIBuilder2 SetPart22(string str)
        {
            parts["part22"] = str;
            return this;
        }
    }

客户端

        static void Main(string[] args)
        {
            Product1 p1 = new ConcreteIBuilder1()
                 .SetPart1("值1")
                 .SetPart2("值2")
                 .SetPart3("值3")
                 .Build();
            p1.Show();
            Product1 p2 = new ConcreteIBuilder2()
                .SetPart11("值11")
                .SetPart22("值22")
                .Build();
            p2.Show();
            Console.Read();
        }

运行结果

 

 

 

内部类建造者

产品和建造者类

    public class Product2
    {
        Builder builder;
        private Product2(Builder builder)
        {
            this.builder = builder;
        }
        public void Operation()
        {
            Console.WriteLine(builder.Parameter1);
            Console.WriteLine(builder.Parameter2);
            Console.WriteLine(builder.Parameter3);
        }
        //建造者在类的内部
        public class Builder
        {
            private string parameter1;
            private string parameter2;
            private string parameter3;
            public string Parameter1 => parameter1;
            public string Parameter2 => parameter2;
            public string Parameter3 => parameter3;
            public Product2 Build()
            {
                if (string.IsNullOrWhiteSpace(parameter1))
                {
                    throw new Exception("parameter1未赋值");
                }
                if (string.IsNullOrWhiteSpace(parameter2))
                {
                    throw new Exception("parameter2未赋值");
                }
                if (string.IsNullOrWhiteSpace(parameter3))
                {
                    throw new Exception("parameter3未赋值");
                }
                return new Product2(this);
            }
            public Builder SetParameter1(string str)
            {
                this.parameter1 = str;
                return this;
            }
            public Builder SetParameter2(string str)
            {
                this.parameter2 = str;
                return this;
            }
            public Builder SetParameter3(string str)
            {
                this.parameter3 = str;
                return this;
            }
        }
    }

 

客户端

        static void Main(string[] args)
        {
            Product2 product2 = new Product2.Builder()
                 .SetParameter1("值1")
                 .SetParameter2("值2")
                 .SetParameter3("值3")
                 .Build();
            product2.Operation();
            Console.Read();
        }

 

运行结果

 

 

优势

封装性好,构建和表示分离。

扩展性好,各个具体的建造者相互独立,有利于系统的解耦。

客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。

使用场景

建造者(Builder)模式和工厂模式的关注点不同:建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用

相同的方法,不同的执行顺序,产生不同的结果。

多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。

缺陷

产品的组成部分必须相同,这限制了其使用范围。

如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。

Demo

posted @ 2021-11-24 22:55  .NET_CJL  阅读(50)  评论(0)    收藏  举报