• 模式说法之——建造者


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

    如何应对种变化呢?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随需求的改变而改变?

     

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

     

     

     

    ·抽象建造者(Builder):给出一个抽象接口,以规范产品对象的各个组成成分的建造。这个接口规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。

    ·具体建造者(Concrete Builder):实现Builder接口,针对不同的商业逻辑,具体化复杂对象的各部分的创建。 在建造过程完成后,提供产品的实例。

    ·指导者(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。

    产品(Product):要创建的复杂对象。

     

    (一)代码

    //复杂的对象

        //各个部分的子对象用一定算法构成

        //各个部分经常面临着剧烈的变化

        public class Product

        {

            List<string> _list = new List<string>();

     

            public void Add(string strPart)

            {

                _list.Add(strPart);

            }

     

            public void Show()

            {

                foreach(string s in _list)

                    Console.WriteLine(s);

            }

        }

     

        //建造者

        public interface IBuilder

        {

            //产品的各个部分

            void BuildPart1();

            void BuildPart2();

            void BuildPartn();

     

            Product GetProduct();

        }

     

        //实现建造者

        public class BuilderA : IBuilder

        {

            private Product _product = new Product();

     

            public void BuildPart1()

            {

                _product.Add("Part 1");

            }

     

            public void BuildPart2()

            {

                _product.Add("Part 2");

            }

     

            public void BuildPartn()

            {

                _product.Add("Part n");

            }

     

            public Product GetProduct()

            {

                return _product;

            }

     

        }

     

        //指导者

        public class Director

        {

            public void CreateProduct(IBuilder builder)

            {

                builder.BuildPart1();

                builder.BuildPart2();

                builder.BuildPartn();

            }

        }

    (二)测试

    [Test]

            public void TestBuilder()

            {

                //建造者

                IBuilder builder = new BuilderA();

     

                //指导者

                Director director = new Director();

     

                //指导

                director.CreateProduct(builder);

     

                //产品

                Product pro = builder.GetProduct();

     

                //产品内容

                pro.Show();

            }

     

    结果:

     

    Part 1

    Part 2

    Part n

     

     

    再举一个比较容易理解的例子

    (一) 产品类

    public class Product

        {

            public delegate void DeleDo();

            public List<DeleDo> _list = new List<DeleDo>();

     

            public void Add(DeleDo i)

            {

                _list.Add(i);

            }

     

            public void Show()

            {

                foreach (DeleDo dd in _list)

                {

                    dd();

                }

            }

    }

    这里一个完整的产品,它由几部分构成,因为它的构建相对稳定,但每个部分却可能发生剧烈变化。因为这个构成如果用别的方法来理解不太好理解,比如:产品类有个字符串的List。这里用委托实现。可以助于理解:构建部分1,……

    (二)建造者接口

    public interface IBuilder

        {

            void Part1();

            void Part2();

            void Part3();

            void Part4();

     

            Product GetProduct();

    }

    产品构建是相对稳定的,但包括的4部分却可能发生剧烈变化。

    (三)实现构造者1

    public class Builder : IBuilder

        {

            Product pro=new Product();

     

            public void p1() { Console.WriteLine("part 1"); }

            public void p2() { Console.WriteLine("part 2"); }

            public void p3() { Console.WriteLine("part 3"); }

            public void p4() { Console.WriteLine("part 4"); }

     

            public void Part1()

            {

                pro.Add(p1);

            }

     

            public void Part2()

            {

                pro.Add(p2);

            }

     

            public void Part3()

            {

                pro.Add(p3);

            }

     

            public void Part4()

            {

                pro.Add(p4);

            }

     

            public Product GetProduct()

            {           

                return pro;

            }

    }

    这里实现了建造者。每实现一部分的的构建,就代表了整个产品构造完成了一部分。这由产品的Add方法实现。

    (四)指挥者

    此部分用于构建相对稳定的产品

    public class Director

        {

            public void CreateProduct(IBuilder builder)

            {

                builder.Part1();

                builder.Part2();

                builder.Part3();

                builder.Part4();

            }

        }

    (五)测试

    public void TestBuilder()

            {

                IBuilder builder = new Builder();

     

                Director d = new Director();

                d.CreateProduct(builder);

     

                Product pro = builder.GetProduct();

     

                pro.Show();

            }

     其中,建造者用于应对产品各部分剧烈的变化;而指挥者是稳定的。

     

    还得来一个例子,这个例子比较真实,能更好的说明这个建造者模式:

     

      /*

             * 要创建的对象是个复杂的对象,它由各部分组成.其中每个部分存在变化,而把部分组成整体的算法不变,即可用建造者

             *

             * 建造者抽象

             * 各个建造者

             * 指导者,把部分按固定的算法组成复杂对象,并返回这个对象

            */

    //产品,car

     

        public class Car

        {

            public void Head(string str)

            {

                Console.WriteLine("head:"+str);

            }

            public void Body(string str)

            {

                Console.WriteLine("body:" + str);

            }

            public void Tail(string str)

            {

                Console.WriteLine("tail:" + str);

            }

        }

     

        public interface IBuilder

        {

            void CreateHead();

            void CreateBody();

            void CreateTail();

     

            Car GetCar();

        }

     

        //jeep builder(jeep factory)

        public class JeepBuilder : IBuilder

        {

            Car car = new Car();

            public void CreateHead()

            {

                car.Head("Jeep");

            }

     

            public void CreateBody()

            {

                car.Body("Jeep");

            }

     

            public void CreateTail()

            {

                car.Tail("Jeep");

            }

     

            public Car GetCar()

            {

                return car;

            }

     

        }

     

        //指挥者,监督者

        public class Director

        {

            public void CreateCar(IBuilder builder)

            {

                builder.CreateTail();

                builder.CreateBody();

                builder.CreateTail();

            }

        } 

        //部分发生变化,例如现在是truck

        public class TruckBuilder : IBuilder

        {

            Car car = new Car();

            public void CreateHead()

            {

                car.Head("Truck");

                Console.WriteLine("creating truck head.");

            }

     

            public void CreateBody()

            {

                car.Body("Truck");

                Console.WriteLine("creating truck body.");

            }

     

            public void CreateTail()

            {

                car.Tail("Truck");

                Console.WriteLine("creating truck tail.");

            }

     

            public Car GetCar()

            {

                return car;

            }

        }

     

     

    [Test]

    public void Test_4_Builder()

    {

        IBuilder builder = new JeepBuilder();

        Director director = new Director();

     

        director.CreateCar(builder);

        Car car=builder.GetCar();

     

        builder = new TruckBuilder();

        director.CreateCar(builder);

        car = builder.GetCar();

        //维持顺序,复杂对象组成算法稳定,部分发生变化.

    }

     

  • 相关阅读:
    国内的maven镜像
    Python Flask UnicodeDecodeError 编码错误解决
    关于Python的web框架
    SDL2+OpenGL (4)混合图像产生动态效果
    什么是OpenGL中的深度、深度缓存、深度测试?
    SDL2+OpenGL (3)纹理映射
    SDL2+OpenGL (2)绘制立体图形
    SDL2+OpenGL (1)绘制多边形
    SDL2中使用OpenGL绘图
    CodeBlocks16.01 MinGW32位 配置SDL2.0.4
  • 原文地址:https://www.cnblogs.com/jams742003/p/1624912.html
Copyright © 2020-2023  润新知