在实际生活中,比如房子装修有很多的步骤,比如贴地转、安装柜子、刷乳胶漆等等。通过这些一系列步骤而最终会得到一个结果,就是装修好的房子。 而往往装修的流程都是固定的,比如一般不会衣柜的都不先安装就先刷漆的。而且对于房子装修而言,名义上为装修,但是我们最终得到的装修效果和我们的用材、风格等有很大的关系,但是结果都是一个装修好的房子, 对于这种固定创建步骤而各个步骤可能有不同的实现方式,但最终都得到一个产品的过程,我们就可以使用建造者模式来实现。
定义: 指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式
类图如下:
在建造者模式中有4个重要的角色。
- 产品角色: 具体要创建的对象、产品
- 抽象建造者:定义创建产品的步骤,以及定义返回具体产品的方法。
- 具体建造者:对抽象建造者的具体实现
- 指挥者:接收传入具体建造者、对创建步骤的控制,生成具体产品
1、场景描述
先需要装修一个房子, 假设只有贴砖、安装柜子、刷漆三个步骤。 而最终由于设计、选材、工艺等的不同。会有现代和北欧两种不同风格的装修效果。
2、实现
// ***********************具体产品***********************/// <summary>/// 具体产品:装修好的房子/// </summary>public class House{/// <summary>/// 砖/// </summary>public string Brick { get; set; }/// <summary>/// 衣柜/// </summary>public string Wardrobe { get; set; }/// <summary>/// 漆/// </summary>public string Paint { get; set; }}// ***********************抽象建造者***********************/// <summary>/// 抽象建造者/// </summary>public abstract class AbstractBuilder{/// <summary>/// 将具体产品(房子)聚合进来/// </summary>protected House house = new House();/// <summary>/// 贴砖/// </summary>public abstract void Tiling();/// <summary>/// 安装衣柜/// </summary>public abstract void InstallWardrobe();/// <summary>/// 刷漆/// </summary>public abstract void Paint();/// <summary>/// 得到装修好的房子/// </summary>/// <returns></returns>public virtual House GetHouse(){return house;}}// ***********************具体建造者***********************/// <summary>/// 具体建造者:北欧风格/// </summary>public class NordicStyleBuilder : AbstractBuilder{public override void InstallWardrobe(){house.Wardrobe = "颗粒板衣柜";}public override void Paint(){house.Paint = "艺术漆";}public override void Tiling(){house.Wardrobe = "佛山转70*140";}}/// <summary>/// 具体建造者:现代风格/// </summary>public class SmartnessStyleBuilder : AbstractBuilder{public override void InstallWardrobe(){house.Wardrobe = "实木衣柜";}public override void Paint(){house.Paint = "乳胶漆";}public override void Tiling(){house.Wardrobe = "广东转80*1600";}}// ***********************指挥者***********************/// <summary>/// 指挥者/// </summary>public class Director{private IBuilder builder;public Director(IBuilder builder){this.builder = builder;}/// <summary>/// 控制装修顺序,得到装修好的房子/// </summary>/// <returns></returns>public House GetHouse(){builder.Tiling();builder.InstallWardrobe();builder.Paint();return builder.GetHouse();}}// ***********************客户端调用***********************IBuilder builder = null;Director director = null;builder = new NordicStyleBuilder();director = new Director(builder);director.GetHouse();Console.WriteLine("北欧风格装修完成");builder = new SmartnessStyleBuilder();director = new Director(builder);director.GetHouse();Console.WriteLine("现代风格装修完成");
3、优缺点
正如所说, 建造者模式将对象的构造与表示分离,产生了很好的解耦作用。具体的实现可以随时进行升级等变化而不影响其他业务逻辑。而且对于不同的建造者,互相之间也不会产生影响。这也体现出了建造者模式很好的封装性。
我们也可以看出来,其实建造者模式也有很大的局限性:它针对的对象的创建,对于具体的建造者而言,都必须遵循指挥者所限制的创建顺序,这一特点就决定了该模式的使用场景。 而且在建造顺序不变化的情况下,建造者模式用起来挺好, 但一当我们需要统一添加新的建造步骤的时候,那所有的具体建造者包括指挥者都需要更改。
4、应用场景
按固定步骤创建复杂对象,而且对于步骤的实现有不同的方式的时候,就可以考虑使用建造者模式。上面说的装修也是很典型的例子。
