一、定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一种对象创建型模式。
二、结构
角色
- 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设计模式之目录