记录《Head First 设计模式》
参考 Graphic Design Patterns网站 与 深入设计模式
目的是检查学习情况,同时方便以后复习。
一、简述
1-1 意图
建造者模式 Builder Pattern:将一个复杂对象的构建与它的表示分离,使得同样的创建过程可以用不同的表示。 又称为生成器模式。该模式是一种 创建型模式 。
1-2 动机
在现实中存在一些复杂对象, 例如电脑,它包括显卡、硬盘、内存、显示屏等组件。对用户来说使用的是完整电脑,而不是使用单独某个部件。
软件开发同样存在复杂的对象类似与电脑,而对象的属性相当于电脑的组件,建造产品的过程就是组合部件的过程。由于组件对象比较复杂,因此组件组合的过程往往被 “外部化”到建造者中,建造者返回用户一个完整的对象。用户无需关心对象所包含的属性以及它们的组装方式。
1-3 模式结构
- Builder:建造者
- ConcreteBuilder1、ConcreteBuilder2 :具体创建者
- Director:指挥者
- Computer:创建对象
1-4 时序图
二、代码示例:
代码实现
组装对象
/// <summary>
/// 电脑类
/// </summary>
public class Computer
{
/// <summary>
/// 电脑组装集合
/// </summary>
private IList<string> parts = new List<string>();
/// <summary>
/// 把单个组件添加到电脑组件集合中
/// </summary>
/// <param name="part"></param>
public void Add(string part)
{
parts.Add(part);
}
/// <summary>
/// 展示电脑组件
/// </summary>
public void Show()
{
Console.WriteLine("电脑开始组装");
foreach (var part in parts)
{
Console.WriteLine("组件" + part + "安装好");
}
Console.WriteLine("电脑组装好了");
}
}
Builder创建者
/// <summary>
/// 抽象建造者,这个场景下为“组装人”,这里也可定义为接口
/// </summary>
public abstract class Builder
{
/// <summary>
/// 装CPU
/// </summary>
public abstract void BuildPartCpu();
/// <summary>
/// 装主板
/// </summary>
public abstract void BuildPartMainBoard();
/// <summary>
/// 获得组装好的电脑
/// </summary>
/// <returns></returns>
public abstract Computer GetComputer();
}
具体构建者
/// <summary>
/// 具体创建者,具体的某个人为具体创建者:例如,装机小王
/// </summary>
public class ConcreteBuilder1:Builder
{
Computer computer = new Computer();
public override void BuildPartCpu()
{
computer.Add("CPU1");
}
public override void BuildPartMainBoard()
{
computer.Add("Main board1");
}
public override Computer GetComputer()
{
return computer;
}
}
/// <summary>
/// 具体创建者,具体的某个人为具体创建者:例如,装机小李
/// </summary>
public class ConcreteBuilder2 : Builder
{
Computer computer = new Computer();
public override void BuildPartCpu()
{
computer.Add("CPU2");
}
public override void BuildPartMainBoard()
{
computer.Add("Main board2");
}
public override Computer GetComputer()
{
return computer;
}
}
指挥者
/// <summary>
///指挥创建过程类
/// </summary>
public class Director
{
public void Construct(Builder builder)
{
builder.BuildPartCpu();
builder.BuildPartMainBoard();
}
}
调试程序
class Program
{
static void Main(string[] args)
{
// 客户找到电脑城老板说要买电脑,这里要装两台电脑
// 创建指挥者和构造者
// 指挥者:老板
Director director = new Director();
//组装者:员工
Builder b1 = new ConcreteBuilder1();
Builder b2 = new ConcreteBuilder2();
// 老板叫员工去组装第一台电脑
director.Construct(b1);
// 组装完,组装人员搬来组装好的电脑
Computer computer1 = b1.GetComputer();
computer1.Show();
// 老板叫员工去组装第二台电脑
director.Construct(b2);
Computer computer2 = b2.GetComputer();
computer2.Show();
}
}
执行结果
三、总结
1-1 模式分析
- 抽象建构者类:定义了产品的 创建方法(BuildPartCpu、BuildPartMainBoard)和 返回方法(GetComputer)。
- 指挥者Director:存在两个作用:一方面隔离客户与生产过程;另一方面它负责控制产品的生产过程。指挥者针对抽象构造者编程,客户端只需要知道具体建造者的类型,即可以通过指挥者类调用具体建造者的相关方法,返回一个完整的产品对象。
- 客户无需关心产品对象的具体组装过程,只需确定具体建造者的类型即可,建造者模式将复杂对象的构建与对象的表现分离开,这样可以使同样的构建过程创建出不同的表现。
1-2 模式优缺点
优点:
- 将一个复杂对象的创建过程封装起来。
- 允许对象通过多个步骤来创建,并且可以改变步骤。
- 向客户隐藏产品内部的表现。
- 客户可以使用不同的具体构建则即可得到不同的产品对象。
- 新增或删除具体建造者无须修改原有类库的代码,指挥者针对抽象构建者编程,系统扩展方便,符合“开闭原则”
缺点:
- 建造者模式创建的产品有较多的共同点,若产品之间的差异性交大,则不使用使用建造者模式,因此使用范围受到一些限制。
- 若产品内部变化复杂,可能会导致需要定义很多具体建造者来实现这些变化,导致系统变得很庞大。
1-3 适合场景
适用场景:
- 需要生成的产品对象有复杂的内部结构,这些对象通常包含多个成员属性。
- 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
- 对象的创建过程独立于创建该对象的类。在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不是建造者类中。
- 隔离复杂对象的创建和使用,并使得相同得创建过程可以创建不同得产品。
1-4 模式应用
模式应用:
枪击游戏中的装备、服装、人物等组成部分,可以使用建造者模式进行设计,通过不同的具体建造者创建不同的人物。
1-5 总结
- 建造者模式封装一个产品得构造过程,并允许按步骤构造。
- 建造者模式包含四个角色:建造者、具体建造者、产品类、指挥者。