一、概念
建造者模式,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。其中,复杂对象是指包含多个成员属性的对象,在工业制造等行业中,这些成员属性也称为部件或零件,例如车辆的发动机、底盘、轮胎等部件,又如初学时常定义的Person类包含的Name、Sex、Age等属性。 与其它创建型模式相同,建造者模式定义一个公用的抽象建造者(Builder),其它具体建造者(ConcreteBuilder)继承自这个抽象基类,形成层次结构。除此,建造者模式 特别引入了指挥者(Director),用以安排复杂对象成员属性的建造次序。
二、实例分析
1.定义复杂对象
public class Actor {
private String type;
private String sex;
private String face;
private String costume;
private String hairstyle;
/* Setter and Getter is omitted*/
}
2.定义抽象建造者抽象建造者代码包含三块内容,实例化一个复杂对象、定义创建复杂对象成员属性的build方法、实现返回复杂对象的工厂方法(为什么叫工厂方法、什么是工厂方法?)
abstract class ActorBuilder {
protected Actor actor = new Actor();
public abstract void buildType();
public abstract void buildSex();
public abstract void buildFace();
public abstract void buildCostume();
public abstract void buildHairstyle();
public Actor createActor() {
return actor;
}
}
3.定义具体建造者具体建造者继承抽象建造者并实现创建复杂对象成员属性的build方法,也可重新实现返回复杂对象的工厂方法。
public class HeroBuilder extends ActorBuilder {
public void buildType() {
actor.setType("Hero");
}
public void buildSex() {
actor.setSex("male");
}
public void buildFace() {
actor.setFace("handsome");
}
public void buildCostume() {
actor.setCostume("armor");
}
public void buildHairstyle() {
actor.setHairstyle("Elegant");
}
}
public class AngelBuilder extends ActorBuilder {
public void buildType() {
actor.setType("Angel");
}
public void buildSex() {
actor.setSex("female");
}
public void buildFace() {
actor.setFace("beautiful");
}
public void buildCostume() {
actor.setCostume("skirt");
}
public void buildHairstyle() {
actor.setHairstyle("Long hair");
}
}
public class DevilBuilder extends ActorBuilder {
public void buildType() {
actor.setType("Devil");
}
public void buildSex() {
actor.setSex("Demon");
}
public void buildFace() {
actor.setFace("Ugly");
}
public void buildCostume() {
actor.setCostume("Black");
}
public void buildHairstyle() {
actor.setHairstyle("Bald");
}
}
4.定义指挥者指挥者实现一个construct()方法用以创建并返回复杂对象,使用时传入一个抽象建造者类型的具体建造者对象,安排复杂对象成员属性的建造次序之后返回。
public class ActorController {
public Actor construct(ActorBuilder ab) {
ab.buildType();
ab.buildSex();
ab.buildFace();
ab.buildCostume();
ab.buildHairstyle();
return ab.createActor();
}
}
5.用于测试的客户端类
客户端通过Java反射机制和配置文件读取灵活创建Builder,实例化具体Builder对象并将这个对象传入Director中获取返回的复杂对象。XMLUtil相关内容クリック文中有简略介绍。
public class Client {
public static void main(String args[]) {
ActorBuilder ab = (ActorBuilder) XMLUtil.getBean();
ActorController ac = new ActorController();
Actor actor = ac.construct(ab);
System.out.println(actor.getType());
System.out.println(actor.getSex());
System.out.println(actor.getFace());
System.out.println(actor.getCostume());
System.out.println(actor.getHairstyle());
}
}
三、总结
在建造者模式中,客户端只需要实例化一个指挥者对象和具体建造者对象,在调用指挥者对象的construct方法时将具体建造者对象作为参数传入,指挥者内部会通过传入的具体建造者对象逐步创建复杂对象的成员属性并将复杂对象返回。
主要优点:
1.在建造者模式中,客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
2.每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或者增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。由于指挥者类针对建造者编程,增加新的具体建造者无需修改原有类库的代码,系统扩展方便,符合“开闭原则”。
3.可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更加方便使用程序来控制创建过程。
主要缺点:
1.建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,例如很多组成部分都不相同,不适合使用建造者模式,因此其使用范围受到一定的限制。
2.如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大,增加系统的理解度和运行成本。