Head First设计模式之生成器模式
一、定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式。
二、结构
角色
- Builder(抽象建造者):它为创建一个产品Product对象的各个部件指定抽象接口,在该接口中一般声明两类方法,一类方法是buildPartX(),它们用于创建复杂对象的各个部件;另一类方法是getResult(),它们用于返回复杂对象。Builder既可以是抽象类,也可以是接口。
- ConcreteBuilder(具体建造者):它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。
- Product(产品角色):它是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。
- Director(指挥者):指挥者又称为导演类,负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。
三、实现
背景:模拟生产各种笔(这里假设笔的零件生产是有顺序的:笔芯 -> 笔壳 -> 组装)
namespace DesignPatterns.Builder
{
class Program
{
static void Main(string[] args)
{
PenDirector director = new PenDirector();
Pen ballpointpen = director.ConstructPen(new BallpointPenBuilder());
Pen brushpen = director.ConstructPen(new BrushPenBuilder());
}
} /// <summary>
/// 创建抽象产品类 -- 笔
/// </summary>
public abstract class Pen
{
/**笔芯**/
private string _cartridge;
/**外壳**/
private string _shell; public string GetCartridge()
{
return _cartridge;
}
public void SetCartridge(string cartridge)
{
this._cartridge = cartridge;
}
public string GetShell()
{
return _shell;
}
public void SetShell(string shell)
{
this._shell = shell;
}
}
public interface IPenBuilder
{
/**
* 生产笔芯
*/
void BuildCartridge();
/**
* 生产外壳
*/
void BuildShell();
/**
* 组装笔
*/
Pen BuildPen();
} /// <summary>
/// 具体产品类 -- 圆珠笔
/// </summary>
public class BallpointPen : Pen
{ public BallpointPen()
{
Console.WriteLine("生产组装圆珠笔");
}
}
/// <summary>
/// 具体产品类 -- 画笔
/// </summary>
public class BrushPen : Pen
{ public BrushPen()
{
Console.WriteLine("生产组装画笔");
}
} /// <summary>
/// 建造者(具体) -- 圆珠笔builder
/// </summary>
public class BallpointPenBuilder : IPenBuilder
{ Pen _pen; public BallpointPenBuilder()
{
_pen = new BallpointPen();
} public void BuildCartridge()
{
_pen.SetCartridge("圆珠笔笔芯");
} public void BuildShell()
{
_pen.SetShell("圆珠笔外壳");
} public Pen BuildPen()
{
return _pen;
} } /// <summary>
/// 建造者(具体) -- 画笔builder
/// </summary>
public class BrushPenBuilder : IPenBuilder
{ Pen _pen; public BrushPenBuilder()
{
_pen = new BrushPen();
} public void BuildCartridge()
{
_pen.SetCartridge("画笔笔芯");
} public void BuildShell()
{
_pen.SetShell("画笔外壳");
} public Pen BuildPen()
{
return _pen;
} } /// <summary>
/// 导演类 Director
/// </summary>
public class PenDirector
{
public Pen ConstructPen(IPenBuilder penBuilder)
{
//生产笔芯
penBuilder.BuildCartridge();
//生产外壳
penBuilder.BuildShell();
//组装笔
return penBuilder.BuildPen();
}
}
}
四、适用场景
需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
对象的创建过程独立于创建该对象的类。在建造者模式中通过引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类和客户类中。
隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品。
五、优缺点
优点:
封装性很好:使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在导演类中对整体而言可以取得比较好的稳定性。
扩展性很好:建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。
有效控制细节风险:由于具体的建造者是独立的,因此可以对建造者过程逐步细化,而不对其他的模块产生任何影响。
缺点:
建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。
欢迎阅读本系列文章:Head First设计模式之目录
Head First设计模式之生成器模式的更多相关文章
- 每天一个设计模式-7 生成器模式(Builder)
每天一个设计模式-7 生成器模式(Builder) 一.实际问题 在讨论工厂方法模式的时候,提到了一个导出数据的应用框架,但是并没有涉及到导出数据的具体实现,这次通过生成器模式来简单实现导出成文本,X ...
- Java设计模式:生成器模式
问题的提出: 有些类很容易创建对象,直接调用其构造方法,例如Student student = new Student("1001","zhang",21); ...
- 【设计模式】- 生成器模式(Builder)
生成器模式 建造者模式.Builder 生成器模式 也叫建造者模式,可以理解成可以分步骤创建一个复杂的对象.在该模式中允许你使用相同的创建代码生成不同类型和形式的对象. 生成器的结构模式 生成器(Bu ...
- Java设计模式-Builder生成器模式
概念: 生成器模式也称之为建造者模式.生成器模式的意图在于将一个复杂的构建与其表示相分离,构建与产品分离. UML: Ibuild接口清晰地反映了创建产品Product的流程. 生成器模式涉及4个关键 ...
- 面向对象设计模式_生成器模式详解(Builder Pattern)
首先提出一个很容易想到应用场景: 手机的生产过程:手机有非常多的子件(部件),成千上万,不同品牌的手机的生产过程都是复杂而有所区别的,相同品牌的手机在设计上也因客户需求多样化,大到型号,小到颜色,是否 ...
- 设计模式十: 生成器模式(Builder Pattern)
简介 生成器模式属于创建型模式的一种, 又叫建造者模式. 生成器模式涉及4个关键角色:产品(Product),抽象生成器(builder),具体生成器(ConcreteBuilder),指挥者(Dir ...
- 面向对象设计模式_生成器模式解读(Builder Pattern)
首先提出一个很容易想到应用场景: 手机的生产过程:手机有非常多的子件(部件),成千上万,不同品牌的手机的生产过程都是复杂而有所区别的,相同品牌的手机在设计上也因客户需求多样化,大到型号,小到颜色,是否 ...
- 设计模式--Builder生成器模式
如果文章中哪里有问题,希望各位大哥大姐指出,小弟十分感激. 正文 什么是生成器模式? 生成器模式就是把生产对象的过程进一步抽取.细化.独立.以往我们生产对象,可能就是在一个小作坊里面从头做到尾.现在用 ...
- go并发设计模式 --资源生成器模式
1.简单的生成器 package main import ( "fmt" "math/rand" ) func GenerateIntA()chan int { ...
随机推荐
- Android破解学习之路(二)——Android游戏 滚动的天空破解
经过上一期的破解教程,相信大家跟我一样都是对破解是初入门,我们破解的目的是什么? 赚钱吗?百度上一大堆破解版的应用,破解的人有赚到钱吗?实实在在的说,其实也是方便自己而已. 玩个游戏,感觉过不去了,来 ...
- Relax信息学题库须知
Relax信息学题库须知 1.本题库于2017.10.15开始建设(建设中),私聊我便可成为题库管理员,关注我即可成为题库成员.我的QQ:2026503022,微信:dy060207. 2.本题库的建 ...
- 利用纯CSS美化checkbox和radio和滑动按钮的实现
W3C提供的CheckBox和radio的原始样式非常的丑,而且在不同的额浏览器表现还不一样,使用常规的方法添加样式没法进行修改样式 一, 单选按钮 <html> <head> ...
- 记录一次参加D2前端技术论坛的杭州之行
前言 在这里,闰土首先要感谢以下两位大佬提供的门票,分别是来自新浪微博部门的H同学,以及来自小米科技的D同学. 当我周六晚上在青旅写完这篇文章过后,第二天上网发现,已经有大佬提前一步在掘金上发布了高质 ...
- 基于 HTML5 Canvas 的 3D 压力器反序列化
在实际应用中,我觉得能够通过操作 JSON 文件来操作 3D 上的场景变化是非常方便的一件事,尤其是在做编辑器进行拖拽图元并且在图元上产生的一系列变化的时候,都能将数据很直观地反应给我们,这边我们简单 ...
- ABAP CDS Table Function介绍与示例
Core data services(以下简称CDS)可以指两样东西,一个是HANA CDS,一个是ABAP CDS. 如我们所知,HANA CDS只支持HANA数据库,ABAP CDS理论上支持多种 ...
- 基于python2.7通过boto3实现ec2表格化
#!/usr/bin/env python import xlwt,xlrd,datetime,json,os,xlutils.copy a={ 'VpcPeeringConnection': { ' ...
- SQL基础教程读书笔记-2
4 数据更新 4.1数据的插入 1.清单{①列清单 ②值清单列清单和值清单的数量必须保持一致.原则上,执行一次INSERT语句会插入一行数据对表进行全列INSERT时,可以省略表名后的列清单2.插入默 ...
- 我的csdn博客搬家了
把csdn上的文章都给搬到我的新博客去了, 将会在新的博客上继续写相关的技术文章 欢迎訪问: http://www.kai-zhou.com
- 002Java概述
1Sun(Stanford University Network )公司1995年推出的高级编程语言 2.面向Internet的编程语言 3.已经成为web应用程序的首选开发语言 4.完全面向对象简单 ...