建造者模式是常用的设计模式。正如其名,建造者模式正如建造者一般,建造的流程是一样的,但是属性不一样,比如一个建楼房的工人,建造的流程都是先打桩,然后搭楼房框架等一系列流程,但是属性比如每个房间的布局,是不一样的,这样就用到了我们的建造者模式。同时,建造者模式方便了初始化的繁杂代码,我们常见到的imageloader初始化就是用的建造者模式,它会统一初始化若干个属性,最后统一设置,若没有建造者模式,就会写一大堆的setXXX属性,代码看着也不简洁。
一、模式定义
建造者模式将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
二、模式结构
建造者模式的UML结构图:
建造者模式主要包含四个角色:
Builder:抽象建造者。它声明为创建一个Product对象的各个部件指定的抽象接口。
ConcreteBuilder:具体建造者。实现抽象接口,构建和装配各个部件。
Director:指挥者。构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。
它主要有两个作用:一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。
而在实际开发中Director经常会被省略,而直接使用一个builder来进行对象的组装,且通常为链式调用。
Product:产品角色。一个具体的产品对象。
三、示例
下面举一个例子,比如一个人(person),每个人都有名字、年龄和性别,这些都是固定的“流程”:
public abstract class Person {
private String name;
private String sex = setSex();
private String age;
Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
//由子类决定性别
public abstract String setSex();
}
这里有一个男人(man):
public class Man extends Person {
@Override
public String setSex() {
return "男";
}
}
然后创建一个建造者抽象类,表示所有person的共同属性,比如每个人都有年龄、名字、性别:
public abstract class Builder<T> {
public abstract Builder setName(String name);
public abstract Builder setAge(String age);
public abstract T build();
}
然后创建一个builder的子类manBuilder,专门来建造man:
public class ManBuilder extends Builder<Man> {
private String name;
private String age;
@Override
public Builder setName(String name) {
this.name = name;
return this;
}
@Override
public Builder setAge(String age) {
this.age = age;
return this;
}
@Override
public Man build() {
Person person = new Man();
person.setAge(age);
person.setName(name);
return (Man) person;
}
}
然后建造一个man的时候只需要:
Builder manBuilder = new ManBuilder();
Man man = (Man)manBuilder.setName("张三").setAge("20").build();
怎么样,很简单吧,这时如果我们想要建一个Woman,先要创建一个专门建造woman的类:
public class Woman extends Person {
@Override
public String setSex() {
return "女";
}
}
public class WomanBuilder extends Builder<Woman> {
private String name;
private String age;
@Override
public Builder setName(String name) {
this.name = name;
return this;
}
@Override
public Builder setAge(String age) {
this.age = age;
return this;
}
@Override
public Woman build() {
Person person = new Woman();
person.setAge(age);
person.setName(name);
return (Woman) person;
}
}
然后只需:
Builder womanBuilder = new WomanBuilder();
Woman woman = (Woman) womanBuilder.setName("小玲").setAge("18").build();
这样就可以了。