建造者模式
建造者模式,把「產品」與「建造過程」與「控制那個流程誰先誰後」,三者分開,三者解耦,符合迪米特原則。
經典的建造者類別圖
Product產品
要做出來的東西
Builder建造者介面
定義要做出東西的「過程」或「步驟」。
以下為要做出東西的方法method:
buildPartA()、buildPartB()、buildPartC()
這些過程是抽象方法,由實作的子類別去覆寫這些方法。
成員屬性有product,用組合(黑色菱形)的方法,用new Product()方式組合在Builder介面。
ConcreateBuilder實作建造者
覆寫抽象方法buildPartA()、buildPartB()、buildPartC()
在這些方法寫上製作這個產品的實際內容。
Director指揮者
成員屬性有builder,用聚合(空心菱形)的方法,用setBuilder()方式聚合。
construct()方法,把製作產品的過程、步驟、方法統整起來,最後傳回一個Product產品出來。
建造各種房子
以上是經典類別圖,現在根據經典類別圖,來建造房子吧!我們要建造小木屋Cabin、別墅Villa二種房子,建造過程一定是不同的。
Builder建造者介面
以下為建立房子的過程:
buildBase()建造地基
buildWalls()建造牆壁
buildRoof()建造屋頂
build()會傳回house物件
ConcreateBuilder實作建造者
CabinBuilder、VillaBuilder有二個建造者。
程式碼
House,這次要建造的產品是房子。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class House {
private String base;
private String roof;
private String wall;
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public String getRoof() {
return roof;
}
public void setRoof(String roof) {
this.roof = roof;
}
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
}
Builder建造者抽象類別
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public abstract class Builder {
// 用組合的方式,把house組合在Builder介面
protected House house = new House();
// 建地基
public abstract void buildBase();
// 建牆壁
public abstract void buildWalls();
// 建屋頂
public abstract void buildRoof();
// 傳回house物件
public House build() {
return house;
}
}
CabinBuilder小木屋建造者
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class CabinBuilder extends Builder{
@Override
public void buildBase() {
house.setBase("木頭地基");
System.out.println("開始建造木頭地基");
}
@Override
public void buildWalls() {
house.setWall("木牆");
System.out.println("開始建造木牆");
}
@Override
public void buildRoof() {
house.setRoof("木製屋頂");
System.out.println("開始建造木製屋頂");
}
}
VillaBuilder別墅建造者
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class VillaBuilder extends Builder{
@Override
public void buildBase() {
house.setBase("鋼筋水泥地基");
System.out.println("開始建造鋼筋水泥地基");
}
@Override
public void buildWalls() {
house.setWall("鋼筋水泥牆");
System.out.println("開始建造鋼筋水泥牆");
}
@Override
public void buildRoof() {
house.setRoof("鋼筋水泥屋頂 + 游泳池");
System.out.println("開始建造防漏水鋼筋水泥屋頂 + 游泳池");
}
}
Director指揮者,負責建造流程與產生房子。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Director {
private Builder builder;
// 用聚合的方式,把builder聚合在Director
public void setBuilder(Builder builder) {
this.builder = builder;
}
// 控管建造流程,最後把建造完成的房子傳回
public House construct() {
builder.buildBase();
builder.buildWalls();
builder.buildRoof();
return builder.build();
}
}
main主程式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class Test {
public static void main(String[] args) {
// 指揮者
Director director = new Director();
System.out.println("==========建造小木屋===========");
// 把小木屋建造者放入參數
director.setBuilder(new CabinBuilder());
// 建造小木屋
House house = director.construct();
System.out.println("Base = " + house.getBase());
System.out.println("Wall = " + house.getWall());
System.out.println("Roof = " + house.getRoof());
System.out.println("========建造別墅=============");
// 把別墅建造者放入參數
director.setBuilder(new VillaBuilder());
// 建造別墅
house = director.construct();
System.out.println("Base = " + house.getBase());
System.out.println("Wall = " + house.getWall());
System.out.println("Roof = " + house.getRoof());
}
}
==========建造小木屋===========
開始建造木頭地基
開始建造木牆
開始建造木製屋頂
Base = 木頭地基
Wall = 木牆
Roof = 木製屋頂
========建造別墅=============
開始建造鋼筋水泥地基
開始建造鋼筋水泥牆
開始建造防漏水鋼筋水泥屋頂 + 游泳池
Base = 鋼筋水泥地基
Wall = 鋼筋水泥牆
Roof = 鋼筋水泥屋頂 + 游泳池