简介:

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


结构图:


优点:

  1. 使得创建代码和表示代码分离,建造者隐藏了该产品是如何组装的,所以若需要改变一个产品内部的表示,只需要再定义一个具体的建造者就可以了;
  2. 便于控制细节风险。

缺点:

  1. 产品必须有共同点,范围有限制;
  2. 若内部变化复杂,会有很多建造者类。

应用场景:

  1. 主要用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但内部的构建通常面临这复杂的变化;
  2. 当创建复杂对象的算法应该独立于该对象的组成部分以及装配方式时;
  3. 需要生产的产品对象的属性相互依赖,需要指定其生成顺序时。

注意事项:

与工厂模式相比,更加关注与零配件的装配顺序。


示例:

1.结构类图的实现

Product类,产品类,由多个部件组成

    /// <summary>
/// 产品类
/// </summary>
public class Product
{
List<string> parts = new List<string>();
/// <summary>
/// 添加产品部件
/// </summary>
/// <param name="part"></param>
public void AddPart(string part)
{
parts.Add(part);
}
/// <summary>
/// 列举所有产品部件
/// </summary>
public void Show()
{
Console.WriteLine("产品创建-----------");
parts.ForEach(x => Console.WriteLine(x));
}
}

Builder类,抽象建造者类,确定产品是由两个部件PartA和PartB组成,并声明一个得到产品建造后的结果的方法GetResult()

    /// <summary>
/// 抽象建造者类
/// </summary>
public abstract class Builder
{
/// <summary>
/// 部件A
/// </summary>
public abstract void BuildPartA();
/// <summary>
/// 部件B
/// </summary>
public abstract void BuildPartB();
/// <summary>
/// 获取产品
/// </summary>
/// <returns>具体产品</returns>
public abstract Product GetResult();
}

ConcreteBuilder类,具体的建造者类

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

Director类,指挥者类,规范产品部件生成的顺序

    /// <summary>
/// 指挥者类
/// </summary>
public class Director
{
public void Construct(Builder builder)
{
builder.BuildPartA();
builder.BuildPartB();
}
}

客户端

     Director director = new Director();
ConcreteBuilder1 builder1 = new ConcreteBuilder1();
director.Construct(builder1);
Product p1 = builder1.GetResult();
p1.Show(); ConcreteBuilder2 builder2 = new ConcreteBuilder2();
director.Construct(builder2);
Product p2 = builder2.GetResult();
p2.Show();

结果

2.建造者模式之西安美食

去西安必须要吃的就是凉皮,肉夹馍,羊肉泡馍...,这些美食会以套餐的形成展示给我们,不同的套餐就是【Product】,一道道美食就是组成【Product】的部件;不同的组合方式就是【Builder】,厨师【Director】将他们搭配起来。

套餐

    /// <summary>
/// 套餐
/// </summary>
public class Meal
{
List<string> parts = new List<string>();
public void AddPart(string part)
{
parts.Add(part);
} public void Show()
{
Console.WriteLine("您的套餐齐了:");
parts.ForEach(x => Console.Write(x + " "));
Console.WriteLine("\n**************");
}
}

套餐创建的抽象类

    /// <summary>
/// 创建套餐
/// </summary>
public abstract class BuildMeal
{
protected Meal meal = new Meal();
public abstract void BuildePartA();
public abstract void BuildePartB();
public abstract void BuildePartC();
public Meal GetMeal()
{
return meal;
}
}

具体套餐的创建

    /// <summary>
/// 经典套餐
/// </summary>
public class BuildClassicalMeal : BuildMeal
{
public override void BuildePartA()
{
meal.AddPart("肉夹馍");
} public override void BuildePartB()
{
meal.AddPart("凉皮");
} public override void BuildePartC()
{
meal.AddPart("冰峰");
}
}
/// <summary>
/// 豪华套餐
/// </summary>
public class BuildLuxuriousMeal : BuildMeal
{
public override void BuildePartA()
{
meal.AddPart("羊肉泡馍");
} public override void BuildePartB()
{
meal.AddPart("糖蒜");
} public override void BuildePartC()
{
meal.AddPart("黑米粥");
}
}

厨师装配

    /// <summary>
/// 厨师
/// </summary>
public class Chef
{
/// <summary>
/// 生成套餐的过程
/// </summary>
/// <param name="buildMeal"></param>
public void GiveMeal(BuildMeal buildMeal)
{
buildMeal.BuildePartA();
buildMeal.BuildePartB();
buildMeal.BuildePartC();
}
}

客户端

    Chef chef = new Chef();
BuildClassicalMeal buildClassical = new BuildClassicalMeal();
chef.GiveMeal(buildClassical);
Meal classicalMeal = buildClassical.GetMeal();
classicalMeal.Show(); BuildLuxuriousMeal buildLuxurious = new BuildLuxuriousMeal();
chef.GiveMeal(buildLuxurious);
Meal luxuriousMeal = buildLuxurious.GetMeal();
luxuriousMeal.Show();

结果

请 多多指教~(看过记得到西安去品尝哟)

设计模式-建造者模式(Builder)的更多相关文章

  1. 设计模式—建造者模式(Builder)

    title: 设计模式-建造者模式 建造者模式(Builder)是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节.建造者模式属于对 ...

  2. 23种设计模式--建造者模式-Builder Pattern

    一.建造模式的介绍       建造者模式就是将零件组装成一个整体,用官方一点的话来讲就是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.生活中比如说组装电脑,汽车等等这些都是建 ...

  3. 设计模式--建造者模式Builder(创建型)

    一.首先看建造者模式的UML图: 二.再来看一个建造者模式的例子 class Builder { public: virtual void BuildHead() {} virtual void Bu ...

  4. 说说设计模式~建造者模式(Builder)

    返回目录 建造者模式是我的"设计模式"里创建型模式里的最后一篇,这种模式在实现中,很多架构都用到了,如MVC,MVP,MVVM,它们都是有建造者模式的精髓的,即,创建与表现分享,我 ...

  5. 大话设计模式--建造者模式 Builder -- C++实现实例

    1. 建造者模式,将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示. 用户只需要指定需要建造的类型就可以得到他们,而具体建造的过程和细节就不需要知道了. 关键类Directo ...

  6. 设计模式:建造者模式(Builder)

    流水作业大家应该都清楚吧!在流水作业中,我们可以将一些复杂的东西给构建出来,例如汽车.我们都知道汽车内部构件比较复杂,由很多部件组成,例如车轮.车门.发动机.方向盘等等,对于我们用户来说我们并不需要知 ...

  7. 设计模式 - 建造者模式 Builder Pattern

    简介 场景 在创建复杂对象时,用户无须关心该对象所包含的属性以及它们的组装方式,只需要指定复杂对象的类型和内容就可以构建它们. 模式定义 建造者模式:将一个复杂对象的构建与表示分离,使得同样的构建过程 ...

  8. [工作中的设计模式]建造者模式builder

    一.模式解析 建造模式是将复杂的内部创建封装在内部,对于外部调用的人来说,只需要传入建造者和建造工具,对于内部是如何建造成成品的,调用者无需关心. 以上是对建造者模式的官方定义,简单说就是对于复杂对象 ...

  9. 【原】iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数

    本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解释建造者模式的概念,那些东西太虚了.设计模式这种东西是为了解决实际问题的,不能为了设计模式而设计模式, ...

  10. 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)

    原文:乐在其中设计模式(C#) - 建造者模式(Builder Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 建造者模式(Builder Pattern) 作者:webabc ...

随机推荐

  1. Mybatis_4.DBUtil.java

    1.获取SqlSessionFactory /** * @author:滕鹏飞 * @version: 1.0 * @Created on: 2018-8-31 下午2:10:45 * 类说明:加载配 ...

  2. Spring整合MybatisPlus学习笔记

    简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生 特性 无侵入:只做增强不做改变,引入它不会对现有 ...

  3. 在 Android 的文字编辑控件 (TEdit) 中, 如何按下 Enter 就隐藏虚拟键盘

    在 Windows 的应用中,我们常常为了让使用者能够快速输入,在Edit元件中的onKeyUp或者 onKeyDown 事件中主动侦测使用者输入的字元是否有换行符号 (Enter),当使用者按下了E ...

  4. 关于 Senparc.Weixin.Cache.Redis 引用的 StackExchange.Redis 版本不匹配的反馈测试

    推测原因是老系统中有地方引用了旧版本的 StackExchange.Redis,原因是 StackExchange.Redis 1.2.6 版本未提供针对 .net 4.6 以上的支持,导致库引用会失 ...

  5. Hive如何处理小文件问题?

    一.小文件是如何产生的 1.动态分区插入数据,产生大量的小文件,从而导致map数量剧增. 2.reduce数量越多,小文件也越多(reduce的个数和输出文件是对应的). 3.数据源本身就包含大量的小 ...

  6. Oracle SQL性能优化的40条军规

    1. SQL语句执行步骤 语法分析> 语义分析> 视图转换 >表达式转换> 选择优化器 >选择连接方式 >选择连接顺序 >选择数据的搜索路径 >运行“执 ...

  7. [Swift]LeetCode757. 设置交集大小至少为2 | Set Intersection Size At Least Two

    An integer interval [a, b] (for integers a < b) is a set of all consecutive integers from ato b, ...

  8. [Swift]LeetCode961. 重复 N 次的元素 | N-Repeated Element in Size 2N Array

    In a array A of size 2N, there are N+1 unique elements, and exactly one of these elements is repeate ...

  9. Oracle视图(和Mysq一样l)

    本章内容: Oracle视图介绍与创建.Oracle视图的查询与修改.Oracle的复杂视图 1. Oracle视图介绍与创建 (1)了解常见的数据库对象都有哪些 (2)了解什么是视图以及为什么要使用 ...

  10. ThinkPHP 数据库操作(二) : 增删改查

    基本使用 可以直接使用数据库运行原生SQL操作了,支持 query (查询操作)和 execute (写入操作)方法,并且支持参数绑定. Db::query('select * from think_ ...