C#设计模式-建造者模式(Builder Pattern)
引言
在软件测试中,一个项目的自动化测试包括UI自动化、API自动化、压力自动化等,把这些不同类型的自动化测试组装在一起变构成了一个项目的自动化测试。通过执行项目的自动化测试变能执行他的所有类型的自动化测试。当然,在生活中也有类似的,比如电脑,由CPU、磁盘、显卡等部分组成,一辆车由轮胎、车体、发动机等部件构成,客户在买车的时候并不知道该车是如何组装的,他只需要会开这辆车就行了。在设计模式中,我们将类似的复杂对象的各个部分按照一定的算法组合在一起,这种对象的创建工作便称为建造者模式。
简介
定义
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象,将复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
主要解决的问题
在软件系统中,有时候面临一个"复杂对象"的创建工作,其通常由各个部分的子对象用一定算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合到一起的算法却相对稳定。如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?
将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 变与不变分离开。
结构图

主要角色
抽象建造者角色(Builder):为创建一个Product对象的各个部件指定抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此角色规定要实现复杂对象的哪些部分的创建,并不涉及具体的对象部件的创建。
具体建造者(ConcreteBuilder)
实现Builder的接口以构造和装配该产品的各个部件。即实现抽象建造者角色Builder的方法。
定义并明确它所创建的表示,即针对不同的商业逻辑,具体化复杂对象的各部分的创建。
提供一个检索产品的接口。
构造一个使用Builder接口的对象即在指导者的调用下创建产品实例。
指导者(Director):调用具体建造者角色以创建产品对象的各个部分。指导者并没有涉及具体产品类的信息,真正拥有具体产品的信息是具体建造者对象。它只负责保证对象各部分完整创建或按某种顺序创建。
产品角色(Product):建造中的复杂对象。它要包含那些定义组件的类,包括将这些组件装配成产品的接口。
具体实现
以一个项目的自动化测试由UI自动化、API自动化、压力自动化组成为例。
产品角色。自动化测试类。
public sealed class AuToTest
{ // 测试用例收集
private IList<string> allCases = new List<string>(); // 将所有的测试用例集中在一起
public void addCases(string testcases)
{
allCases.Add(testcases);
} // 进行测试
public void Test()
{
Console.WriteLine("============ 开始执行测试用例 ============");
foreach (string cases in allCases)
{
Console.WriteLine(cases + "执行完毕!");
}
Console.WriteLine("============ 执行测试用例结束 ============");
}
}
抽象建造者:包含创建产品各个子部件的抽象方法。自动化测试类。
public abstract class Builder
{ // 创建UI自动化测试用例
public abstract void BuildCasesUI(); // 创建接口自动化测试用例
public abstract void BuildCasesAPI(); // 创建性能自动化测试
public abstract void BuildCasesStress(); // 获得组装好的
public abstract AuToTest GetAuToTest();
}
具体建造者:实现了抽象建造者接口。以百度自动化测试和华为自动化测试为例。
public class BaiduBuidler : Builder
{
AuToTest BaiduAutoTest = new AuToTest();
public override void BuildCasesUI()
{
BaiduAutoTest.addCases("百度 UI 自动化测试");
} public override void BuildCasesAPI()
{
BaiduAutoTest.addCases("百度 API 自动化测试");
} public override void BuildCasesStress()
{
BaiduAutoTest.addCases("百度 Stress 自动化测试");
} public override AuToTest GetAuToTest()
{
return BaiduAutoTest;
}
} /// 具体创建者,比如华为
public class HuaWeiBuidler : Builder
{
AuToTest HuaWeiAutoTest = new AuToTest();
public override void BuildCasesUI()
{
HuaWeiAutoTest.addCases("华为 UI 自动化测试");
} public override void BuildCasesAPI()
{
HuaWeiAutoTest.addCases("华为 API 自动化测试");
} public override void BuildCasesStress()
{
HuaWeiAutoTest.addCases("华为 Stress 自动化测试");
} public override AuToTest GetAuToTest()
{
return HuaWeiAutoTest;
}
}
指挥者:调用建造者中的方法完成复杂对象的创建。将UI自动化、API自动化、压力自动化组建成项目自动化测试。
public class Director
{
// 所有自动化测试组装成一个项目的自动化
public void Construct(Builder builder)
{
builder.BuildCasesUI();
builder.BuildCasesAPI();
builder.BuildCasesStress();
}
}
客户类。
class Customer
{
static void Main(string[] args)
{
Director director = new Director();
Builder baiduBuilder = new BaiduBuidler();
Builder huaweiBuidler = new HuaWeiBuidler(); // 百度项目进行组装
director.Construct(baiduBuilder);
// 组装完成后进行执行项目的自动化测试
AuToTest baiduAutoTest = baiduBuilder.GetAuToTest();
baiduAutoTest.Test(); // 华为项目进行自动化测试
director.Construct(huaweiBuidler);
AuToTest huaweiAutoTest = huaweiBuidler.GetAuToTest();
huaweiAutoTest.Test();
}
}
完整代码
using System;
using System.Collections.Generic; namespace 建造者模式
{
/// <summary>
/// 客户端
/// </summary>
class Customer
{
static void Main(string[] args)
{
Director director = new Director();
Builder baiduBuilder = new BaiduBuidler();
Builder huaweiBuidler = new HuaWeiBuidler(); // 百度项目进行组装
director.Construct(baiduBuilder);
// 组装完成后进行执行项目的自动化测试
AuToTest baiduAutoTest = baiduBuilder.GetAuToTest();
baiduAutoTest.Test(); // 华为项目进行自动化测试
director.Construct(huaweiBuidler);
AuToTest huaweiAutoTest = huaweiBuidler.GetAuToTest();
huaweiAutoTest.Test();
}
} /// <summary>
/// 建造者模式中的指挥者
/// 不同类型的组装,Construct 方法里面的实现就是创建复杂对象固定算法的实现,是相对稳定的
/// </summary>
public class Director
{
// 所有自动化测试组装成一个项目的自动化
public void Construct(Builder builder)
{
builder.BuildCasesUI();
builder.BuildCasesAPI();
builder.BuildCasesStress();
}
} /// <summary>
/// 自动化测试类
/// </summary>
public sealed class AuToTest
{ // 测试用例收集
private IList<string> allCases = new List<string>(); // 将所有的测试用例集中在一起
public void addCases(string testcases)
{
allCases.Add(testcases);
} // 进行测试
public void Test()
{
Console.WriteLine("============ 开始执行测试用例 ============");
foreach (string cases in allCases)
{
Console.WriteLine(cases + "执行完毕!");
}
Console.WriteLine("============ 执行测试用例结束 ============");
}
} /// <summary>
/// 抽象建造者,定义自动化测试时需要那些内容,和最后创建的结果
/// 在这儿要和组装进行区分,这不是组装的类型
/// </summary>
public abstract class Builder
{ // 创建UI自动化测试用例
public abstract void BuildCasesUI(); // 创建接口自动化测试用例
public abstract void BuildCasesAPI(); // 创建性能自动化测试
public abstract void BuildCasesStress(); // 获得组装好的
public abstract AuToTest GetAuToTest();
} /// <summary>
/// 具体创建者,就是什么项目进行自动化测试,比如百度
/// </summary>
public class BaiduBuidler : Builder
{
AuToTest BaiduAutoTest = new AuToTest();
public override void BuildCasesUI()
{
BaiduAutoTest.addCases("百度 UI 自动化测试");
} public override void BuildCasesAPI()
{
BaiduAutoTest.addCases("百度 API 自动化测试");
} public override void BuildCasesStress()
{
BaiduAutoTest.addCases("百度 Stress 自动化测试");
} public override AuToTest GetAuToTest()
{
return BaiduAutoTest;
}
} /// <summary>
/// 具体创建者,就是什么项目进行自动化测试,比如华为
/// </summary>
public class HuaWeiBuidler : Builder
{
AuToTest HuaWeiAutoTest = new AuToTest();
public override void BuildCasesUI()
{
HuaWeiAutoTest.addCases("华为 UI 自动化测试");
} public override void BuildCasesAPI()
{
HuaWeiAutoTest.addCases("华为 API 自动化测试");
} public override void BuildCasesStress()
{
HuaWeiAutoTest.addCases("华为 Stress 自动化测试");
} public override AuToTest GetAuToTest()
{
return HuaWeiAutoTest;
}
} }
执行结果
============ 开始执行测试用例 ============
百度 UI 自动化测试执行完毕!
百度 API 自动化测试执行完毕!
百度 Stress 自动化测试执行完毕!
============ 执行测试用例结束 ============
============ 开始执行测试用例 ============
华为 UI 自动化测试执行完毕!
华为 API 自动化测试执行完毕!
华为 Stress 自动化测试执行完毕!
============ 执行测试用例结束 ============
适用场景
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
- 相同的方法,不同的执行顺序,产生不同的事件结果时。
- 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。
- 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能。
- 创建一些复杂的对象时,这些对象的内部组成构件间的建造顺序是稳定的,但是对象的内部组成构件面临着复杂的变化。
优缺点
优点:
- 封装性好,构建和表示分离。
- 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
- 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。
缺点:
- 产品的组成部分必须相同,这限制了其使用范围。
- 如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
与工厂模式区别
- 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
- 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
- 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
- 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。
C#设计模式-建造者模式(Builder Pattern)的更多相关文章
- 设计模式 - 建造者模式 Builder Pattern
简介 场景 在创建复杂对象时,用户无须关心该对象所包含的属性以及它们的组装方式,只需要指定复杂对象的类型和内容就可以构建它们. 模式定义 建造者模式:将一个复杂对象的构建与表示分离,使得同样的构建过程 ...
- 23种设计模式--建造者模式-Builder Pattern
一.建造模式的介绍 建造者模式就是将零件组装成一个整体,用官方一点的话来讲就是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示.生活中比如说组装电脑,汽车等等这些都是建 ...
- 【原】iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数
本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解释建造者模式的概念,那些东西太虚了.设计模式这种东西是为了解决实际问题的,不能为了设计模式而设计模式, ...
- 乐在其中设计模式(C#) - 建造者模式(Builder Pattern)
原文:乐在其中设计模式(C#) - 建造者模式(Builder Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 建造者模式(Builder Pattern) 作者:webabc ...
- 【设计模式】建造者模式 Builder Pattern
前面学习了简单工厂模式,工厂方法模式以及抽象工厂模式,这些都是创建类的对象所使用的一些常用的方法和套路, 那么如果我们创建一个很复杂的对象可上面的三种方法都不太适合,那么“专业的事交给专业人去做”,2 ...
- iOS设计模式之:建造者模式Builder Pattern,用于改进初始化参数
转自:http://www.cnblogs.com/wengzilin/p/4365855.html 本文主要讨论一下iOS中的Builder Pattern.与网上很多版本不同,本文不去长篇大论地解 ...
- 设计模式系列之建造者模式(Builder Pattern)——复杂对象的组装与创建
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 二十四种设计模式:建造者模式(Builder Pattern)
建造者模式(Builder Pattern) 介绍将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 示例用同样的构建过程创建Sql和Xml的Insert()方法和Get()方 ...
- 建造者模式(Builder Pattern)
建造者模式(Builder Pattern) 它可以将多个简单的对象一步一步构建成一个复杂的对象. 意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示. 主要解决:主要解决在软 ...
- 设计模式—建造者模式(Builder)
title: 设计模式-建造者模式 建造者模式(Builder)是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节.建造者模式属于对 ...
随机推荐
- 洛谷 P6851 【onu】贪心
题目描述 题目传送门 分析 因为小 \(D\) 打出的牌与小 \(C\) 打出的牌花色必须相同,所以我们需要按照花色分类讨论 对于某一种花色 如果小 \(C\) 没有这种花色的牌但是小 \(D\) 有 ...
- OAuth 2.0 Server PHP实现示例
需求实现三方OAuth2.0授权登录 使用OAuth服务OAuth 2.0 Server PHP 环境nginx mysqlphp 框架Yii 一 安装 项目目录下安装应用 composer.phar ...
- javascript 原型与原型链浅析
原型 和原型链 什么是原型链 简单理解就是原型组成的链,对象的__proto__它的是原型,而原型也是一个对象,也有__proto__属性,原型的__proto__又是原型的原型,就这样可以一直通过_ ...
- navicat 生成注册码( 仅供学习使用 )
前言,由于navicat使用比较顺手,刚好前段时间试用期到,又看看了怎么生成注册码,特地记录下使用 . 1.运行 找到 navicat 文件(exe) 2.生成注册文件(报错好,后续会用到) 3.断网 ...
- Gradle的构建过程都不会?带你全面了解Android如何自定义Gradle 插件
目前 Android 工程的默认构建工具为 Gradle,我们在构建 APK 的时候往往会执行 ./gradlew assembleDebug 这样的命令.. 那么这个命令到底代表着什么含义呢?命令的 ...
- js、css等文件引入空白问题
路径没错,不管路径怎么改变,js.css等文件就是引入失败.很多时候是因为Spring的过滤器把js.css等资源文件拦截了.default是tomcat配置的一个servlet,"Defa ...
- 单源文件目录makefile
目录结构 由于只是用来编译简单的小型程序,所以目录尽量简洁: . ├── build │ ├── bin │ ├── .dep │ └── obj ├── makefile └── src ...
- 每个人都可以用C语言写的推箱子小游戏!今天你就可以写出属于自己项目~
C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...
- 干货分享:用一百行代码做一个C/C++表白小程序,程序员的浪漫!
前言:很多时候,当别人听到你是程序员的时候.第一印象就是,格子衫.不浪漫.直男.但是程序员一旦浪漫起来,真的没其他人什么事了.什么纪念日,生日,情人节,礼物怎么送? 做一个浪漫的程序给她,放上你们照片 ...
- centOS7 查看防火墙状态 开放端口
一.防火墙的开启.关闭.禁用命令 (1)设置开机启用防火墙:systemctl enable firewalld.service (2)设置开机禁用防火墙:systemctl disable fire ...