一 场景
比如我们要修一座房子,会先打地基在造墙体最后在盖屋顶,这些都是通过工人来实现的,我们只关心最后的房子是什么样子
建造者模式 是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节
二 uml
- Product(产品角色): 一个具体的产品对象
- Builder(抽象建造者): 创建一个Product对象的各个部件指定的 接口/抽象类
- ConcreteBuilder(具体建造者): 实现接口,构建和装配各个部件
- Director(指挥者): 构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程
三 建造者模式实现
定义产品(房子)
@Getter
@Setter
@ToString
public class House {
/**
* 地基
*/
private String base;
/**
* 墙体
*/
private String wall;
/**
* 屋顶
*/
private String roofed;
}
定义抽象建造者
public abstract class HouseBuilder {
/**
* 构造地基
*/
abstract void buildBase();
/**
* 构造墙体
*/
abstract void buildWall();
/**
* 构造房顶
*/
abstract void buildRoofed();
/**
* 获取产品
* @return
*/
abstract House build();
}
具体建造者
public class CommonHouseBuilder extends HouseBuilder{
private House house;
public CommonHouseBuilder() {
this.house = new House();
}
@Override
void buildBase() {
house.setBase("5m地基");
}
@Override
void buildWall() {
house.setWall("5m高的墙");
}
@Override
void buildRoofed() {
house.setRoofed("普通房顶");
}
@Override
House build() {
return this.house;
}
}
public class HighHouseBuilder extends HouseBuilder {
private House house;
public HighHouseBuilder() {
this.house = new House();
}
@Override
void buildBase() {
house.setBase("10m地基");
}
@Override
void buildWall() {
house.setWall("10m高的墙");
}
@Override
void buildRoofed() {
house.setRoofed("高级房顶");
}
@Override
House build() {
return this.house;
}
}
指挥者 确保了房子的建造顺序
public class HouseDirector {
public House createHouse(HouseBuilder houseBuilder){
houseBuilder.buildBase();
houseBuilder.buildWall();
houseBuilder.buildRoofed();
House house = houseBuilder.build();
return house;
}
}
客户端调用
public class Client {
public static void main(String[] args) {
CommonHouseBuilder commonHouseBuilder = new CommonHouseBuilder();
HouseDirector houseDirector = new HouseDirector();
House house = houseDirector.createHouse(commonHouseBuilder);
System.out.println(house);
HighHouseBuilder highHouseBuilder = new HighHouseBuilder();
House highHouse = houseDirector.createHouse(highHouseBuilder);
System.out.println(highHouse);
}
}
四 优缺点
-
优点:
1.客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
2.每一个具体建造者都独立,因此可以方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。
3.可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
4.增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭”。
-
缺点:
1.当建造者过多时,会产生很多类,难以维护。
2.建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,若产品之间的差异性很大,则不适合使用该模式,因此其使用范围受到一定限制。
3.若产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。