建造者模式是指将一个“复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示“。
“复杂对象的构建和它的表示分离”可以理解成一辆汽车,无论使用何种品牌的部件,只要能正常安装即可。
“使得同样的构建过程可以创建不同的表示”即同样的部件可采取多种安装方式。
建造者模式由四个角色组成:
(1)Builder(抽象建造者角色)
为创建一个Product对象的各个部件指定抽象接口。
(2)ConcreteBuilder(具体建造者角色)
实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,提供一个检索产品的接口。
(3)Director(导演者角色)
构造一个使用Builder接口的对象。
(4)Product(产品角色)
表示被构造的复杂对象,ConcreteBuilder创建该产品的内部表示并定义它的装配过程。包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
举个例子,如果要造一个房子,那么四个角色分别要做的工作是:抽象的建造者,制造房子需要哪些步骤;具体建造者,按步骤造好房子,返还房子;导演者,调派建筑工来按步骤建房子;产品角色即房子。
优势及使用环境:
优势:客户端无需了解产品内部情况;通过新的具体建造者,即可改变产品的内部结构;四个角色构成相互独立,具备高扩展性;通过对建造过程的细化,可降低项目维护的风险。
使用情形:产品对象有一个较复杂的内部结构,并且其具体的构建方法面临者复杂的变化时;产品类的构造过程中,可使被构造对象有不同表现时。创建对象时,需要调用软件系统的其他对象。
盖房子的例子:
定义产品角色:房子
public class Room {
private String wall;
private String window;
private String door;
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getWindow() {
return window;
}
public void setWindow(String window) {
this.window = window;
}
public String getDoor() {
return door;
}
public void setDoor(String door) {
this.door = door;
}
}
定义抽象建造者:通用要求
//工人接口,定义了工人要进行的工作,负责具体的建造,墙,窗子,门等
//房子是建筑工人建设的,建设完成后,由民工把房子交给房主
public interface Builder {
public void makeWall();
public void makeWindow();
public void makedoor();
public Room getRoom();
}
定义具体建造者:建筑工人会建造各个部件。
public class ConcreteBuilder implements Builder{
private Room room = new Room();
@Override
public void makeWall() {
room.setWall("红砖墙");
}
@Override
public void makeWindow() {
room.setWindow("绣花窗");
}
@Override
public void makedoor() {
room.setWindow("紫檀木门");
}
@Override
public Room getRoom() {
return room;
}
}
定义导演者:指挥工人工作。 他知道房子应该怎么设计,但他不会自己去建造,而是指挥民工去建造。
public class Designer {
public void order(Builder builder){
builder.makeWall();
builder.makeWindow();
builder.makedoor();
}
}
房主,来验收房子了。 房主的任务就是聘请一个民工,一个设计师,同时把民工给设计师指挥,督促设计师开展工作。最后从民工手上收房。
public class Client {
public static void main(String[] args){
Designer designer = new Designer();
ConcreteBuilder builder = new ConcreteBuilder();
designer.order(builder);
Room newRoom = builder.getRoom();
System.out.println(newRoom);
}
}
这样一个房子就建设完成了。由于房子是工人在建设的,最后是向工人要房子。
普遍的示例代码:
// 产品类
public class Product {
public void doSomething(){
// TODO
}
}
// 抽象建造者
public abstract class Builder {
public abstract void setPart();
public abstract Product buildProduct();
}
// 具体建造者
public class ConcreteProduct extends Builder{
private Product product = new Product();
@Override
public void setPart() {
// TODO
}
@Override
public Product buildProduct() {
return product;
}
}
// 测试类
public class Test {
private Builder builder = new ConcreteProduct();
public Product getProduct(){
builder.setPart();
return builder.buildProduct();
}
}