引言

在软件测试中,一个项目的自动化测试包括UI自动化、API自动化、压力自动化等,把这些不同类型的自动化测试组装在一起变构成了一个项目的自动化测试。通过执行项目的自动化测试变能执行他的所有类型的自动化测试。当然,在生活中也有类似的,比如电脑,由CPU、磁盘、显卡等部分组成,一辆车由轮胎、车体、发动机等部件构成,客户在买车的时候并不知道该车是如何组装的,他只需要会开这辆车就行了。在设计模式中,我们将类似的复杂对象的各个部分按照一定的算法组合在一起,这种对象的创建工作便称为建造者模式。

简介

定义

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象,将复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

主要解决的问题

在软件系统中,有时候面临一个"复杂对象"的创建工作,其通常由各个部分的子对象用一定算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合到一起的算法却相对稳定。如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?
将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 变与不变分离开。

结构图

主要角色

  • 抽象建造者角色(Builder):为创建一个Product对象的各个部件指定抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此角色规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。

  • 具体建造者(ConcreteBuilder)

    • 实现Builder的接口以构造和装配该产品的各个部件。即实现抽象建造者角色Builder的方法。

    • 定义并明确它所创建的表示,即针对不同的商业逻辑,具体化复杂对象的各部分的创建。

    • 提供一个检索产品的接口。

    • 构造一个使用Builder接口的对象即在指导者的调用下创建产品实例。

  • 指导者(Director):调用具体建造者角色以创建产品对象的各个部分。指导者并没有涉及具体产品类的信息,真正拥有具体产品的信息是具体建造者对象。它只负责保证对象各部分完整创建或按某种顺序创建。

  • 产品角色(Product):建造中的复杂对象。它要包含那些定义组件的类,包括将这些组件装配成产品的接口。

具体实现

以一个项目的自动化测试由UI自动化、API自动化、压力自动化组成为例。

产品角色。自动化测试类。

  1. public sealed class AuToTest
  2. {
  3.  
  4. // 测试用例收集
  5. private IList<string> allCases = new List<string>();
  6.  
  7. // 将所有的测试用例集中在一起
  8. public void addCases(string testcases)
  9. {
  10. allCases.Add(testcases);
  11. }
  12.  
  13. // 进行测试
  14. public void Test()
  15. {
  16. Console.WriteLine("============ 开始执行测试用例 ============");
  17. foreach (string cases in allCases)
  18. {
  19. Console.WriteLine(cases + "执行完毕!");
  20. }
  21. Console.WriteLine("============ 执行测试用例结束 ============");
  22. }
  23. }

抽象建造者:包含创建产品各个子部件的抽象方法。自动化测试类。

  1. public abstract class Builder
  2. {
  3.  
  4. // 创建UI自动化测试用例
  5. public abstract void BuildCasesUI();
  6.  
  7. // 创建接口自动化测试用例
  8. public abstract void BuildCasesAPI();
  9.  
  10. // 创建性能自动化测试
  11. public abstract void BuildCasesStress();
  12.  
  13. // 获得组装好的
  14. public abstract AuToTest GetAuToTest();
  15. }

具体建造者:实现了抽象建造者接口。以百度自动化测试和华为自动化测试为例。

  1. public class BaiduBuidler : Builder
  2. {
  3. AuToTest BaiduAutoTest = new AuToTest();
  4. public override void BuildCasesUI()
  5. {
  6. BaiduAutoTest.addCases("百度 UI 自动化测试");
  7. }
  8.  
  9. public override void BuildCasesAPI()
  10. {
  11. BaiduAutoTest.addCases("百度 API 自动化测试");
  12. }
  13.  
  14. public override void BuildCasesStress()
  15. {
  16. BaiduAutoTest.addCases("百度 Stress 自动化测试");
  17. }
  18.  
  19. public override AuToTest GetAuToTest()
  20. {
  21. return BaiduAutoTest;
  22. }
  23. }
  24.  
  25. /// 具体创建者,比如华为
  26. public class HuaWeiBuidler : Builder
  27. {
  28. AuToTest HuaWeiAutoTest = new AuToTest();
  29. public override void BuildCasesUI()
  30. {
  31. HuaWeiAutoTest.addCases("华为 UI 自动化测试");
  32. }
  33.  
  34. public override void BuildCasesAPI()
  35. {
  36. HuaWeiAutoTest.addCases("华为 API 自动化测试");
  37. }
  38.  
  39. public override void BuildCasesStress()
  40. {
  41. HuaWeiAutoTest.addCases("华为 Stress 自动化测试");
  42. }
  43.  
  44. public override AuToTest GetAuToTest()
  45. {
  46. return HuaWeiAutoTest;
  47. }
  48. }

指挥者:调用建造者中的方法完成复杂对象的创建。将UI自动化、API自动化、压力自动化组建成项目自动化测试。

  1. public class Director
  2. {
  3. // 所有自动化测试组装成一个项目的自动化
  4. public void Construct(Builder builder)
  5. {
  6. builder.BuildCasesUI();
  7. builder.BuildCasesAPI();
  8. builder.BuildCasesStress();
  9. }
  10. }

客户类。

  1. class Customer
  2. {
  3. static void Main(string[] args)
  4. {
  5. Director director = new Director();
  6. Builder baiduBuilder = new BaiduBuidler();
  7. Builder huaweiBuidler = new HuaWeiBuidler();
  8.  
  9. // 百度项目进行组装
  10. director.Construct(baiduBuilder);
  11. // 组装完成后进行执行项目的自动化测试
  12. AuToTest baiduAutoTest = baiduBuilder.GetAuToTest();
  13. baiduAutoTest.Test();
  14.  
  15. // 华为项目进行自动化测试
  16. director.Construct(huaweiBuidler);
  17. AuToTest huaweiAutoTest = huaweiBuidler.GetAuToTest();
  18. huaweiAutoTest.Test();
  19. }
  20. }

完整代码

  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. namespace 建造者模式
  5. {
  6. /// <summary>
  7. /// 客户端
  8. /// </summary>
  9. class Customer
  10. {
  11. static void Main(string[] args)
  12. {
  13. Director director = new Director();
  14. Builder baiduBuilder = new BaiduBuidler();
  15. Builder huaweiBuidler = new HuaWeiBuidler();
  16.  
  17. // 百度项目进行组装
  18. director.Construct(baiduBuilder);
  19. // 组装完成后进行执行项目的自动化测试
  20. AuToTest baiduAutoTest = baiduBuilder.GetAuToTest();
  21. baiduAutoTest.Test();
  22.  
  23. // 华为项目进行自动化测试
  24. director.Construct(huaweiBuidler);
  25. AuToTest huaweiAutoTest = huaweiBuidler.GetAuToTest();
  26. huaweiAutoTest.Test();
  27. }
  28. }
  29.  
  30. /// <summary>
  31. /// 建造者模式中的指挥者
  32. /// 不同类型的组装,Construct 方法里面的实现就是创建复杂对象固定算法的实现,是相对稳定的
  33. /// </summary>
  34. public class Director
  35. {
  36. // 所有自动化测试组装成一个项目的自动化
  37. public void Construct(Builder builder)
  38. {
  39. builder.BuildCasesUI();
  40. builder.BuildCasesAPI();
  41. builder.BuildCasesStress();
  42. }
  43. }
  44.  
  45. /// <summary>
  46. /// 自动化测试类
  47. /// </summary>
  48. public sealed class AuToTest
  49. {
  50.  
  51. // 测试用例收集
  52. private IList<string> allCases = new List<string>();
  53.  
  54. // 将所有的测试用例集中在一起
  55. public void addCases(string testcases)
  56. {
  57. allCases.Add(testcases);
  58. }
  59.  
  60. // 进行测试
  61. public void Test()
  62. {
  63. Console.WriteLine("============ 开始执行测试用例 ============");
  64. foreach (string cases in allCases)
  65. {
  66. Console.WriteLine(cases + "执行完毕!");
  67. }
  68. Console.WriteLine("============ 执行测试用例结束 ============");
  69. }
  70. }
  71.  
  72. /// <summary>
  73. /// 抽象建造者,定义自动化测试时需要那些内容,和最后创建的结果
  74. /// 在这儿要和组装进行区分,这不是组装的类型
  75. /// </summary>
  76. public abstract class Builder
  77. {
  78.  
  79. // 创建UI自动化测试用例
  80. public abstract void BuildCasesUI();
  81.  
  82. // 创建接口自动化测试用例
  83. public abstract void BuildCasesAPI();
  84.  
  85. // 创建性能自动化测试
  86. public abstract void BuildCasesStress();
  87.  
  88. // 获得组装好的
  89. public abstract AuToTest GetAuToTest();
  90. }
  91.  
  92. /// <summary>
  93. /// 具体创建者,就是什么项目进行自动化测试,比如百度
  94. /// </summary>
  95. public class BaiduBuidler : Builder
  96. {
  97. AuToTest BaiduAutoTest = new AuToTest();
  98. public override void BuildCasesUI()
  99. {
  100. BaiduAutoTest.addCases("百度 UI 自动化测试");
  101. }
  102.  
  103. public override void BuildCasesAPI()
  104. {
  105. BaiduAutoTest.addCases("百度 API 自动化测试");
  106. }
  107.  
  108. public override void BuildCasesStress()
  109. {
  110. BaiduAutoTest.addCases("百度 Stress 自动化测试");
  111. }
  112.  
  113. public override AuToTest GetAuToTest()
  114. {
  115. return BaiduAutoTest;
  116. }
  117. }
  118.  
  119. /// <summary>
  120. /// 具体创建者,就是什么项目进行自动化测试,比如华为
  121. /// </summary>
  122. public class HuaWeiBuidler : Builder
  123. {
  124. AuToTest HuaWeiAutoTest = new AuToTest();
  125. public override void BuildCasesUI()
  126. {
  127. HuaWeiAutoTest.addCases("华为 UI 自动化测试");
  128. }
  129.  
  130. public override void BuildCasesAPI()
  131. {
  132. HuaWeiAutoTest.addCases("华为 API 自动化测试");
  133. }
  134.  
  135. public override void BuildCasesStress()
  136. {
  137. HuaWeiAutoTest.addCases("华为 Stress 自动化测试");
  138. }
  139.  
  140. public override AuToTest GetAuToTest()
  141. {
  142. return HuaWeiAutoTest;
  143. }
  144. }
  145.  
  146. }

执行结果

  1. ============ 开始执行测试用例 ============
  2. 百度 UI 自动化测试执行完毕!
  3. 百度 API 自动化测试执行完毕!
  4. 百度 Stress 自动化测试执行完毕!
  5. ============ 执行测试用例结束 ============
  6. ============ 开始执行测试用例 ============
  7. 华为 UI 自动化测试执行完毕!
  8. 华为 API 自动化测试执行完毕!
  9. 华为 Stress 自动化测试执行完毕!
  10. ============ 执行测试用例结束 ============

适用场景

  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
  • 相同的方法,不同的执行顺序,产生不同的事件结果时。
  • 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。
  • 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能。
  • 创建一些复杂的对象时,这些对象的内部组成构件间的建造顺序是稳定的,但是对象的内部组成构件面临着复杂的变化。

优缺点

优点:

  • 封装性好,构建和表示分离。
  • 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
  • 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。

缺点:

  • 产品的组成部分必须相同,这限制了其使用范围。
  • 如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。

与工厂模式区别

  • 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
  • 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
  • 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
  • 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。

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

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

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

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

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

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

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

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

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

  5. 【设计模式】建造者模式 Builder Pattern

    前面学习了简单工厂模式,工厂方法模式以及抽象工厂模式,这些都是创建类的对象所使用的一些常用的方法和套路, 那么如果我们创建一个很复杂的对象可上面的三种方法都不太适合,那么“专业的事交给专业人去做”,2 ...

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

    转自:http://www.cnblogs.com/wengzilin/p/4365855.html 本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解 ...

  7. 设计模式系列之建造者模式(Builder Pattern)——复杂对象的组装与创建

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  8. 二十四种设计模式:建造者模式(Builder Pattern)

    建造者模式(Builder Pattern) 介绍将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 示例用同样的构建过程创建Sql和Xml的Insert()方法和Get()方 ...

  9. 建造者模式(Builder Pattern)

    建造者模式(Builder Pattern) 它可以将多个简单的对象一步一步构建成一个复杂的对象. 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 主要解决:主要解决在软 ...

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

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

随机推荐

  1. 使用响应扩展的响应面(Rx)

    下载demo - 196 KB 下载source - 98 KB 表的内容 系统要求反应面一个简单的计时器从事件中收集数据序列使用更复杂的查询订阅您希望完成的面最终考虑历史 介绍 "Rx&q ...

  2. Codeforces Global Round 11 个人题解(B题)

    Codeforces Global Round 11 1427A. Avoiding Zero 题目链接:click here 待补 1427B. Chess Cheater 题目链接:click h ...

  3. MySQL 复制表(表结构、表结构和数据)

    MySQL 中使用 命令行 复制表结构及数据的方法主要有以下几种: 1.只复制表结构 CREATE TABLE new_table SELECT * FROM old_table WHERE 1=2: ...

  4. const、define 和 static 的区别

    目录 define.const static define.const 在 C++ 中,const 和 define 都可以用来定义常量.但是这二者之间有很大的区别: define 的作用 用 def ...

  5. Python+Appium自动化测试(4)-使用weditor进行元素定位

    一,weditor的安装与使用 首选需要在电脑上配置好Python环境 下载安装命令如下,加上镜像下载速度更快: pip install weditor -i https://pypi.tuna.ts ...

  6. DM9000网卡驱动分析(转)

    s3c6410自带的DM9000网卡驱动也是基于platform设备模型. 其定义的设备资源在arch/arm/mach-s3c64xx/mach-smdk6410中.有网卡的resource res ...

  7. python接口测试之日志功能

    之前在简书中看了一篇关于日志功能的文档,供大家参考:https://www.jianshu.com/p/62f7b49b41e7 Python通过logging模块提供日志功能,所以直接导入即可 im ...

  8. 生物信息-McScan(Python-jcvi)共线性画图

    比较基因组学中,共线性的分析的图无疑是最漂亮的. 共线性分析可以很好地解释进化关系和多倍化事件. 本文主要介绍的是唐老师的Python版McScan(jcvi工具包),这个包很强大,但是其功能在官网的 ...

  9. 【Azure Redis 缓存 Azure Cache For Redis】当使用Jedis客户端连接Redis时候,遇见JedisConnectionException: Could not get a resource from the pool / Redis connection lost

    问题情形 当在执行Redis一直指令时,有可能会遇见如下几种错误: 1) redis.clients.jedis.exceptions.JedisConnectionException: Could ...

  10. pyqt5安装后 pyqt-tools却无法安装解决方法!

    逛了逛国外论坛 这哥们跟我一样 我一晚上没睡 就为了这个 原来 我的py版本太高级了 我把py3.9卸载了 换上了老旧的3.76版本 成功了