一、概述
在软件系统中,把构造对象实例的逻辑移到了类的外部,在这个类的外部定义了类的逻辑。它把一个复杂对象的构造过程从对象的表示中分离出来了,其直接效果是将一个复杂的对象简化为一个比较简单的目标对象。它强调的是产品构造过程。
二、意图
将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
三、Builder模式的结构
Builder:为创建Product对象的各个部件指定抽象接口。
ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
Director:构造一个使用Builer接口的对象。
Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,以及将这些部件装配成最终产品的接口。
四、举例:
我们用KFC套餐为例,KFC中存在以下对象,各种食物Product,有收银员Director,可配置套餐菜单接口(主食+零食+饮料)Builder,具体套餐搭配ConcreteBuilder。
1. 首先给定可配置套餐菜单接口(主食+零食+饮料)Builder:
abstract public class Builder{// BuildPartA,BuildPartB,BuildPartC具体的套餐方法abstract public void BuildPartA();abstract public void BuildPartB();abstract public void BuildPartC();abstract public Product GetResult();}
2.我们需要KFC的产品:
public class Product{ArrayList parts = new ArrayList();public void Add(string part){parts.Add(part);}public void Show(){Console.WriteLine(" Product Parts -------");foreach (string part in parts)Console.WriteLine(part);}}
3. 然后,我们给出具体套餐搭配ConcreteBuilderA:
public class ConcreteBuilderA:Builder{private Product product;// Methodsoverride public void BuildPartA(){product = new Product();product.Add("麦香鸡腿堡");}override public void BuildPartB(){product.Add("加冰可乐");}override public void BuildPartC(){product.Add("大薯条");}override public Product GetResult(){return product;}}
4. 然后,我们给出具体套餐搭配ConcreteBuilderB:
public class ConcreteBuilderB:Builder{private Product product;// Methodsoverride public void BuildPartA(){product = new Product();product.Add("香辣鸡腿堡");}override public void BuildPartB(){product.Add("可乐不加冰");}override public void BuildPartC(){product.Add("小薯条");}public override Product GetResult(){return product;}}
5. 现在我们需要一个收银员Director:
public class Director{public void Construct(Builder builder){builder.BuildPartA();builder.BuildPartB();builder.BuildPartC();}}
6. 最后我们完成Client购买KFC套餐:
class Program{static void Main(string[] args){Director director = new Director();Builder b1 = new ConcreteBuilderA();Builder b2 = new ConcreteBuilderB();director.Construct(b1);Product p1 = b1.GetResult();p1.Show();director.Construct(b2);Product p2 = b2.GetResult();p2.Show();Console.ReadKey();}}
这样Client分别买了两种不同的套餐,Client只需要让收款员知道你需要那种套餐即可,不需要了解具体套餐是如何实现的。
五、优点:
1.建造者模式的“加工工艺”是暴露的,这样使得建造者模式更加灵活。
2.解耦了组装过程和创建具体部件,使得我们不用去关心每个部件是如何组装的。--上面对KFC的分析可以很清楚的看出这点。
六、适用环境:
1.需要生成的产品对象有复杂的内部结构。
2.需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
3.在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。
参考文献:
《.NET应用架构设计原则、模式与实践》 王洋 著