设计模式(8)-Builder生成器模式1

0参考

https://www.cnblogs.com/zhenyulu/articles/37378.html?share_token=928e8c30-1303-4e02-925f-970e787f7b40

1、Builder模式的应用起因和动机

1.1起因

1.2动机

1.3意图(GoF)

将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。(《设计模式GoF》)

2算法逻辑

2.1算法逻辑图

2.2协作过程图

2.3各模块功能

从上面的协作图中可以看出,指导者角色是与客户端打交道的角色。指导者角色将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但却不为客户端所知。

3、各代码测试模块

3.1Director

担任这个角色的类调用具体建造者角色以创建产品对象。客户会这个角色去创建产品。

    //(1) "Director",指导者(导演)
    public class Director
    {
        // Methods
        public void Construct(Builder builder)
        {
            builder.BuildPartA();
            builder.BuildPartB();
        }
    }

3.2 Builder

创建建造者的抽象类(当然也可以用interface接口来实现),给出一个抽象接口,以规范产品对象的各个组成成分的建造。

 // (2)"Builder",构造者的抽象类
public abstract class Builder
{
        // Methods
        //(2.1)创建A部分抽象方法
        abstract public void BuildPartA();
        //(2.2)创建B部分抽象方法
        abstract public void BuildPartB();
        //(2.3)返回最终抽象产品的抽象方法
        abstract public Product GetResult();
 }

3.3 Product

Product是指一个具体的产品,需要注意的是

// (3)"Product",一个具体的产品
// 注意1:它可能由好几部件组成
// 注意2:它的组合顺序搞不好有讲究的
// 注意3:它的实现还可能以后会经常变,但是建造的流程(套路或顺序)不变
public class Product
{
        // (3.1)Fields,部件存储(定义)的简单例子
        ArrayList parts = new ArrayList();

        // (3.2)Methods,添加部件的方法
        public void Add(string part)
        {
            parts.Add(part);
        }
        // (3.3)简单展示部件的方法
        public void Show()
        {
            Console.WriteLine(" Product Parts -------");
            foreach (string part in parts)
                Console.WriteLine(part);
        }
}

3.4 ConcreteBuilder

具体的建造者,担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括:

虽然和产品精密相关,但是如果产品的构造流程不改,那么一般这个类也不用大修改!

 //(4.1)具体的建造者例子1
// "ConcreteBuilder1"
public class ConcreteBuilder1 : Builder
{
        // Fields
        private Product? product = null;

        // Methods
        public override void BuildPartA()
        {
            product = new Product();
            product.Add("PartA_1");
        }
        public override void BuildPartB()
        {
            product?.Add("PartB_1");
        }

        public override Product GetResult()
        {
            return product;
        }
}
//(4.2)具体的建造者例子2
// "ConcreteBuilder2"
public class ConcreteBuilder2 : Builder
{
        // Fields
        private Product? product = null;

        // Methods
        public override void BuildPartA()
        {
            product = new Product();
            product.Add("PartA_2");
        }
        public override void BuildPartB()
        {
            product?.Add("PartB_2");
        }

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

3.5 Client

(1)客户(另一个项目组的客户程序),它来调用Director,输入不同的具体ConcreteBuilder。简单的测试

public static void Main()
{            
					//(一)简单测试
            //(1)先创建一个指导者(导演)Director
            Director director = new Director();

            //(2)创建2个测试用的具体建造者
            Builder b1 = new ConcreteBuilder1();
            Builder b2 = new ConcreteBuilder2();

            //(3)构建产品并展示
            director.Construct(b1);
            Product p1 = b1.GetResult();
            p1.Show();

            director.Construct(b2);
            Product p2 = b2.GetResult();
            p2.Show();
}

(2)封装一下的客户端

 //升级封装一下,客户端的应用
public class ClientBuilder
{
        public Director? director = null;

        //构建方法1
        public void CreateDirector()
        {
            this.director = new Director();
        }

        //构建方法2
        public void SetDirector(Director? director)
        { 
            this.director = director; 
        }
        //业务逻辑根据需要修改
        public void ConstructProductAndShow(Builder b)
        {
            this.director?.Construct(b);
            Product p = b.GetResult();
            p.Show();
        }
}
public static void Main()
{       
            //(二)简单封装后的测试
            ClientBuilder clientBuilder = new ClientBuilder();
            clientBuilder.SetDirector(new Director());

            clientBuilder.ConstructProductAndShow(new ConcreteBuilder1());
            clientBuilder.ConstructProductAndShow(new ConcreteBuilder2());
}
    

4、完整测试程序

(1)测试代码结构,由2个文件组成

(2)构建者builder.cs中的代码


using System.Collections;

namespace ConsoleApp8_bulider
{
    // (1)"Director",指导者(导演)
    public class Director
    {
        // Methods
        public void Construct(Builder builder)
        {
            builder.BuildPartA();
            builder.BuildPartB();
        }
    }
    //-----------------------------------------//
    // (2)"Builder",构造者的抽象类
    public abstract class Builder
    {
        // Methods
        //(2.1)创建A部分抽象方法
        abstract public void BuildPartA();
        //(2.2)创建B部分抽象方法
        abstract public void BuildPartB();
        //(2.3)返回最终抽象产品的抽象方法
        abstract public Product GetResult();
    }
    // (3)"Product",一个具体的产品
    // 注意1:它可能由好几部件组成
    // 注意2:它的组合顺序搞不好有讲究的
    // 注意3:它的实现还可能以后会经常变,但是建造的流程(套路或顺序)不变
    public class Product
    {
        // (3.1)Fields,部件存储(定义)的简单例子
        ArrayList parts = new ArrayList();

        // (3.2)Methods,添加部件的方法
        public void Add(string part)
        {
            parts.Add(part);
        }
        // (3.3)简单展示部件的方法
        public void Show()
        {
            Console.WriteLine(" Product Parts -------");
            foreach (string part in parts)
                Console.WriteLine(part);
        }
    }
    //-----------------------------------------//
    //(4.1)具体的建造者例子1
    // "ConcreteBuilder1"
    public class ConcreteBuilder1 : Builder
    {
        // Fields
        private Product? product = null;

        // Methods
        public override void BuildPartA()
        {
            product = new Product();
            product.Add("PartA_1");
        }
        public override void BuildPartB()
        {
            product?.Add("PartB_1");
        }

        public override Product GetResult()
        {
            return product;
        }
    }
    //(4.2)具体的建造者例子2
    // "ConcreteBuilder2"
    public class ConcreteBuilder2 : Builder
    {
        // Fields
        private Product? product = null;

        // Methods
        public override void BuildPartA()
        {
            product = new Product();
            product.Add("PartA_2");
        }
        public override void BuildPartB()
        {
            product?.Add("PartB_2");
        }

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

(3)客户端client.cs中的代码

using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;

namespace ConsoleApp8_bulider
{
    //升级封装一下,客户端的应用
    public class ClientBuilder
    {
        public Director? director = null;

        //构建方法1
        public void CreateDirector()
        {
            this.director = new Director();
        }

        //构建方法2
        public void SetDirector(Director? director)
        { 
            this.director = director; 
        }
        //业务逻辑根据需要修改
        public void ConstructProductAndShow(Builder b)
        {
            this.director?.Construct(b);
            Product p = b.GetResult();
            p.Show();
        }
    }
    class Demo
    {
        public static void Main()
        {
            //(一)简单测试
            ////(1)先创建一个指导者(导演)Director
            //Director director = new Director();

            ////(2)创建2个测试用的具体建造者
            //Builder b1 = new ConcreteBuilder1();
            //Builder b2 = new ConcreteBuilder2();

            ////(3)构建产品并展示
            //director.Construct(b1);
            //Product p1 = b1.GetResult();
            //p1.Show();

            //director.Construct(b2);
            //Product p2 = b2.GetResult();
            //p2.Show();

            //(二)简单封装后的测试
            ClientBuilder clientBuilder = new ClientBuilder();
            clientBuilder.SetDirector(new Director());

            clientBuilder.ConstructProductAndShow(new ConcreteBuilder1());
            clientBuilder.ConstructProductAndShow(new ConcreteBuilder2());
        }
    }
}

(4)测试结果

(5)客户端调用说明

客户端只和指导者、具体的建造者打交道,如果对象由改变,只需要:添加修改具体的对象和建造者就可以。

(6)另外相对稳定的部分,在指导者里面,Director中的Construct里的内容和顺序应该是比较稳定的。

5.几个模式的对比

5.1工厂方法模式和建造者模式

5.2抽象工厂和建造者模式

抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式则是不需要关心构建过程,只关心什么产品由什么工厂生产即可。

建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品。

如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车。

6、小结

展开阅读全文

页面更新:2024-05-10

标签:模式   指导者   生成器   抽象   部件   角色   对象   工厂   测试   方法   产品

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top