生成器(Builder)模式:创建型模式
将一个复杂的对象的构建(builder)和它的表示(复杂对象生成的director类)分离,使得同样的构建过程可以创建不同的表示。核心是给指导者(Director)一个生成器,但具体方式不指定。
动机
在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成,由于需求的变
化,这个复杂对象的各个部分子对象经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
如何应对这种变化?如何提供一种“封闭机制”来隔离出“复杂对象各个部分”的变化,从而保持系统中“稳定的构建算法”不
随着需求改变而改变?
要点
Builder模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象
的各个部分则经常变化。变化在哪里就封装哪里--Builder模式主要在于应对“复杂对象各个部分”的频繁需求变
动;其缺点在于难以应对“分步骤构建算法”的需求变化。抽象工厂模式解决“系列对象”的需求变化,Builder模式
解决“对象部分”的需求变化。Builder模式通常与Composite模式组合使用。
类图
协作图
类图及组成角色
四种角色(5种包括客户端):
产品(Product):具体生产器要构造的复杂对象,它的各个组成部分由ConcreteBuilder生成,生成过程由Director(指导类)控制。注意该类中只提供了get方法,这个看具体需求。
抽象生成器(Builder):声明了生成器应包含的创建产品各个组成部件的方法。注意,这些方法只是生成对象的各组成部分,各方法相互独立,方法间无时序关系,也不存在“总”的生成方法。另外,Builder应包含获取生成的产品的方法。
具体生产器(ConcreteProduct):实现Builder接口的类,具体生成器将实现Builder接口所定义的方法;每种不同的产品都有一个专属的ConcreteBuilder。
指导类(Director):用于控制产品的生成过程。Director的控制对象是Builder,即通过Director实现了对各类型产品的生成过程的重用。
客户端(Client):是生成器模式的使用者。对Client来说,生成的最终产品Product的类型是明确的,生成Product所使用的具体生成器ConcreteBuilder也是明确的。
优点
1.将复杂对象的构建和表示进行解耦,用户无需了解对象的具体组件,对象创建具有更大的灵活性。
2.可以更加精细有效地控制对象的构造过程。
3.满足开-闭原则:当增加新的具体生成器时,不必修改指挥者的代码。
1.当系统创建结构复杂的对象时,对象的组成和装配方式须分离,构造方法中编写的对象无法分离。
2.构造过程必须允许被构造对象有不同表示时。
代码示例:
//生成器抽象类或接口,用于构建Product对象
public abstract class Builder {
//构建部件A
public abstract void BuildPartA();
//构建部件B
public abstract void BuildPartB();
//返回构建的Product对象
public abstract Product GetBuildResult();
}
//指挥者类,用来指挥建造过程
public class Director {
public Product GetProduct(Builder builder) {
builder.BuildPartA();
builder.BuildPartB();
return builder.GetBuildResult();
}
}
//具体建造者类
public class ConcreteBuilder1 :Builder {
private Product product = new Product();
public void BuildPartA() {
product.Add("部件A");
}
public void BuildPartB() {
product.Add("部件B");
}
public Product GetBuildResult() {
return product;
}
}
// 具体建造者类,建造的对象时Product,通过build使Product完善
public class ConcreteBuilder2 :Builder {
private Product product = new Product();
public void BuildPartA() {
product.Add("部件X");
}
public void BuildPartB() {
product.Add("部件Y");
}
public Product GetBuildResult() {
return product;
}
}
//产品类,由多个部件组成
public class Product {
List<string> parts = new List<string>();
// 添加产品部件
public void Add(String part) {
parts.Add(part);
}
// 列举所有的产品部件
public void Show() {
Console.WriteLine("---产品 创建---");
foreach(var part in parts) {
Console.WriteLine(part);
}
}
}
//建造客户端
public class BuilderClient {
public static void Main(string[] args) {
Director director = new Director();
Builder builder1 = new ConcreteBuilder1();
Builder builder2 = new ConcreteBuilder2();
Product product1 = Director.GetProduct(builder1);
product1.Show();
Product product2 = Director.GetProduct(builder2);
product2.Show();
}
}