C# 设计模式5 建造者(Builder)

参考:head first 设计模式

应用场景

将一个复杂对象的构建与它的表示分享开,使得同样的创建可以创建不同的表示对象。建造者使创建与表示分离,客户端无须知道内部的创建细节(对客户而言,隐藏了这个过程)。降低了耦合度。
比如我们要去买一台或多台电脑,如果我们去采购主板,显卡,硬盘,键盘等再去组装,会累死。可以将一电脑的组装过程封装到一个建造者类中,建造者只需要返回客户端建造完毕的对象即可。
通常是老板让装机师傅按配置清单装机即可。
再比如我们去饭店吃饭,同样的道理。

结构

抽象工厂:AbstractFactory 定义创建产品的功能(可以接口或抽象类),它为访问类提供了一个创建一组相关或相互依赖对象的接口,它是工厂方法模式的升级。
具体工厂:ConcreteSugarFactory 定义创建何种产品
抽象产品:Sugar 定义产品的特征和功能(可为接口或抽象类)
具体产品:WhiteSugar BrownSugar 实现抽象产品功能特征的实现

图例

在这里插入图片描述

特点

优点:
各个具体的建造者相互独立,利于扩展。客户端无须知道产品创建细节及内部组成。
缺点:
产品的组成部分必须相同,限制了它的使用范围。如果产品内部变化复杂,会增加更多的建造者类。

工厂方法与建造者模式比较

建造者模式注重零部件的组装过程,而工厂方法注重创建过程。

系统自带
//.net自带的建造者模式:System.Text.StringBuilder,它是一种演化,没有指挥者角色和抽象建造者角色
//StringBuilder类即扮演着具体建造者角色,也同时扮演了拇挥者角色和抽象建造者的角色
//此时建造者的实现如下:
//建造者模式的演变:省略了指挥者和抽象建造者角色   
//StringBuilder类扮演着建造string对象的具体建造者角色,其中的ToString()方法
//用来返回具体产品给客户端,Append用来创建产品的组件
StringBuider sb = new StringBuilder();
//创建过程
sb.Append("a");
sb.Append("b");
//获取结果
sb.ToString();
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPattern
{
    public class BuilderPatternClient
    {  
        public static void main()
        {
            //客户找到老板说要两台电脑  
            //创建指挥者和构造者
            BossDirector dir = new BossDirector();
            Builder b1 = new ConcreteBuilderI3();
            Builder b2 = new ConcreteBuilderI5();

            //老板让人员1去组装并取回结果
            dir.SendCmd(b1);
            Computer cmp1 = b1.GetComputer();
            cmp1.Show();

            //老板让人员2去组装并取回结果
            dir.SendCmd(b2);
            Computer cmp2 = b2.GetComputer();
            cmp2.Show();

            //简化的构造者模式
            BuilderPatterClientSimple.main();
        }
    }

    /// <summary>
    /// 要创建的对象
    /// </summary>
    public class Computer
    {
        private IList<string> parts = new List<string>();

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

        public void Show()
        {
            foreach (var p in parts)
            {
                Console.WriteLine(p + "组装完成");
            }
        }
    }

    /// <summary>
    /// 创建过程类
    /// </summary>
    public class BossDirector
    {
        /// <summary>
        /// 下命令让人员去组装
        /// </summary>
        /// <param name="b"></param>
        public void SendCmd(Builder b)
        {
            b.BuildCpu();
            b.BuildDisk();
        }
    }

    //
    /// <summary>
    /// 抽象建造者,这个场景下为“组装人”,可义为抽象类或接口
    /// </summary>
    public abstract class Builder
    {
        //组装过程
        public abstract void BuildCpu();
        public abstract void BuildDisk();

        //获取结果 
        public abstract Computer GetComputer();
    }

    /// <summary>
    /// 不同的创建者,对应不同配置的电脑
    /// </summary>
    public class ConcreteBuilderI3 : Builder
    {
        private Computer cmp = new Computer();

        public override void BuildCpu()
        {
            cmp.Add("cpui3");
        }

        public override void BuildDisk()
        {
            cmp.Add("disk 128g");
        }

        public override Computer GetComputer()
        {
            return cmp;
        }
    }

    /// <summary>
    /// 不同的创建者,对应不同配置的电脑
    /// </summary>
    public class ConcreteBuilderI5 : Builder
    {
        private Computer cmp = new Computer();

        public override void BuildCpu()
        {
            cmp.Add("cput i5");
        }

        public override void BuildDisk()
        {
            cmp.Add("disk 512g");
        }

        public override Computer GetComputer()
        {
            return cmp;
        }
    }
    
    //此时具体建造者角色扮演了指挥者和建造者两个角色
    public class Builder1
    {
        private Product product = new Product();

        public void BuildOne()
        {
            product.Add("1");
        }

        public void BuildTwo()
        {
            product.Add("2");
        }

        public Product GetProduct()
        {
            return product;
        }

        /// <summary>
        /// 指挥者角色的代码
        /// </summary>
        public void Construct()
        {
            BuildOne();
            BuildTwo();
        }
    }

    /// <summary>
    /// 产品类
    /// </summary>
    public class Product
    {
        private IList<string> parts = new List<string>();

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

        public void Show()
        {
            foreach (var p in parts)
            {
                Console.WriteLine(p + "完成");
            }
        }
    }

    /// <summary>
    /// 简化的创建者模式调用
    /// </summary>
    public class BuilderPatterClientSimple
    {
        private static Builder1 builder;

        public static void main()
        {
            builder = new Builder1();
            builder.Construct();
            Product product = builder.GetProduct();
            product.Show();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值