设计模式

第 7 章 Builder 模式 -- 组装复杂的实例

2018-09-02  本文已影响0人  oO反骨仔Oo
image.png

Builder 模式

概念:组装具有复杂结构的实例可以称为 Builder 模式。

Show me the code

image.png
namespace BuilderPattern
{
    /// <summary>
    /// 建造者
    /// </summary>
    public abstract class Builder
    {
        /// <summary>
        /// 整理标题
        /// </summary>
        /// <param name="title"></param>
        public abstract void MakeTitle(string title);

        /// <summary>
        /// 整理字符串
        /// </summary>
        /// <param name="str"></param>
        public abstract void MakeString(string str);

        /// <summary>
        /// 整理项
        /// </summary>
        /// <param name="items"></param>
        public abstract void MakeItems(string[] items);

        /// <summary>
        /// 关闭
        /// </summary>
        public abstract void Close();
    }
}
namespace BuilderPattern
{
    /// <summary>
    /// 监工
    /// </summary>
    internal class Director
    {
        private readonly Builder _builder;

        public Director(Builder builder)
        {
            _builder = builder;
        }

        /// <summary>
        /// 构建
        /// </summary>
        public void Construct()
        {
            _builder.MakeTitle("Greeting");
            _builder.MakeString("从早上至下午");
            _builder.MakeItems(new[] {"早上好", "下午好"});

            _builder.MakeString("晚上");
            _builder.MakeItems(new[] {"晚上好", "晚安", "再见"});
            _builder.Close();
        }
    }
}
using System.Text;

namespace BuilderPattern
{
    /// <summary>
    /// 文本建造者
    /// </summary>
    internal class TextBuilder : Builder
    {
        private readonly StringBuilder _sb = new StringBuilder();

        public override void MakeTitle(string title)
        {
            _sb.AppendLine("==========");
            _sb.AppendLine($"【{title}】");
        }

        public override void MakeString(string str)
        {
            _sb.AppendLine($"~{str}");
            _sb.AppendLine();
        }

        public override void MakeItems(string[] items)
        {
            foreach (var t in items)
            {
                _sb.AppendLine($"* {t}");
            }

            _sb.AppendLine();
        }

        public override void Close()
        {
            _sb.AppendLine("==========");
        }

        public string GetResult()
        {
            return _sb.ToString();
        }
    }
}
using System.Text;

namespace BuilderPattern
{
    /// <summary>
    /// HTML 建造者
    /// </summary>
    public class HtmlBuilder : Builder
    {
        private readonly StringBuilder _sb = new StringBuilder();

        public override void MakeTitle(string title)
        {
            _sb.AppendLine($"<html><head><title>{title}</title></head><body>");
            _sb.AppendLine($"<h1>{title}</h1>");
        }

        public override void MakeString(string str)
        {
            _sb.AppendLine($"<p>{str}</p>");
        }

        public override void MakeItems(string[] items)
        {
            _sb.AppendLine("<ul>");

            foreach (var item in items)
            {
                _sb.AppendLine($"<li>{item}</li>");
            }

            _sb.AppendLine("</ul>");
        }

        public override void Close()
        {
            _sb.AppendLine("</body></html>");
        }

        public string GetResult()
        {
            return _sb.ToString();
        }
    }
}
using System;

namespace BuilderPattern
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var textBuilder = new TextBuilder();
            var director = new Director(textBuilder);
            director.Construct();
            var result = textBuilder.GetResult();
            Console.WriteLine(result);

            Console.WriteLine("===== 上:TextBuilder;下:HtmlBuilder =====");

            var htmlBuilder = new HtmlBuilder();
            director = new Director(htmlBuilder);
            director.Construct();
            result = htmlBuilder.GetResult();
            Console.WriteLine(result);

            Console.Read();
        }
    }
}
image.png

角色梳理

Builder:建造者

负责定义用于生成实例的接口。

ConcreteBuilder:具体的建造者

负责实现 Builder 抽象类定义的接口,示例中的 TextBuilder 类和 HtmlBuilder 类。

Director:监工

负责调用 Builder 的接口来生成实例,不依赖 ConcreteBuilder,示例中的 Director 类。

Client:使用者

只是调用方,示例中的 Program 类。

image.png
image.png

相关模式

Template Method 模式

Builder 模式中,Director 角色控制 Builder 角色;Template Method 模式中,父类控制子类的行为。

Composite 模式

Abstract Factory 模式

都应用于生成复杂的实例。。

Facade 模式

Builder 模式中,Director 角色组合 Builder 角色中的复杂方法对外提供简单生成实例的接口方法;Facade 模式中的 Facade 角色是通过组合内部模块向外部提供简单调用的接口。

要点 & 思路

1.示例中,使用 Builder 可以组装具有复杂结构的实例,但是组装的具体过程则被隐藏在了 Director 中。

上一篇下一篇

猜你喜欢

热点阅读