思路:多态下,建造不同类型的“建筑”,通过第三方监工监制,用户调用监工即可
场景之一:盖房子举例,房子本身有很多个组成部分,各组件息息相关缺一不可,否则房倒屋塌。而其构造过程也是相当复杂的,但大家不必担心,为响应我们简约直观的一贯宗旨,这里只将其简化拆分成地基、墙体、屋顶三部分,首先来看建筑物类。
package com.yitian.builder;
import java.util.ArrayList;
import java.util.List;
/**
* @Description 建筑物
* @Author yitianRen
* @Date 2019/9/17 10:34
* @Version 1.0
**/
public class Building {
// 用来模拟房子组件的堆叠
private List<String> buildingComponents = new ArrayList<>();
public void setBasement(String basement) {// 地基
this.buildingComponents.add(basement);
}
public void setWall(String wall) {// 墙体
this.buildingComponents.add(wall);
}
public void setRoof(String roof) {// 房顶
this.buildingComponents.add(roof);
}
@Override
public String toString() {
String buildingStr = "";
for (int i = buildingComponents.size() - 1; i >= 0; i--) {
buildingStr += buildingComponents.get(i);
}
return buildingStr;
}
}
为了模拟建筑物通用类中各组件的建造顺序,我们在第以List来模拟三个组件的堆叠,之后是它们对应的三个建造方法,最后于的toString方法自下而上的打印出最终完成的房子。看起来是不难,但怎样从这个类直接构造出一个房子呢?怎样去设置这些字符串的组件属性呢?此时客户端一头雾水,还是找个专业施工方吧,先定义个施工方接口。
package com.yitian.builder;
/**
* @Author:yitianRen
* @Date:10:37 2019/9/17
* Description:施工者 建造
*/
public interface Builder {
public void buildBasement();
public void buildWall();
public void buildRoof();
public Building getBuilding();
}
别墅施工者:
package com.yitian.builder;
/**
* @Description 建造别墅
* @Author yitianRen
* @Date 2019/9/17 10:39
* @Version 1.0
**/
public class HouseBuilder implements Builder {
private Building house;
public HouseBuilder() {
house = new Building();
}
@Override
public void buildBasement() {
System.out.println("挖地基,部署管道、线缆,水泥加固,搭建围墙、花园。");
house.setBasement("╬╬╬╬╬╬╬╬\n");
}
@Override
public void buildWall() {
System.out.println("搭建木质框架,石膏板封墙并粉饰内外墙。");
house.setWall("|田|田 田|\n");
}
@Override
public void buildRoof() {
System.out.println("建造木质屋顶、阁楼,安装烟囱,做好防水。");
house.setRoof("╱◥███◣\n");
}
@Override
public Building getBuilding() {
return house;
}
}
公寓施工者:
package com.yitian.builder;
/**
* @Description 建造八层公寓
* @Author yitianRen
* @Date 2019/9/17 10:42
* @Version 1.0
**/
public class ApartmentBuilder implements Builder {
private Building apartment;
public ApartmentBuilder() {
apartment = new Building();
}
@Override
public void buildBasement() {
System.out.println("深挖地基,修建地下车库,部署管道、线缆、风道。");
apartment.setBasement("╚═════════╝\n");
}
@Override
public void buildWall() {
System.out.println("搭建多层建筑框架,建造电梯井,钢筋混凝土浇灌。");
for (int i = 0; i < 8; i++) {// 此处假设固定8层
apartment.setWall("║ □ □ □ □ ║\n");
}
}
@Override
public void buildRoof() {
System.out.println("封顶,部署通风井,做防水层,保温层。");
apartment.setRoof("╔═════════╗\n");
}
@Override
public Building getBuilding() {
return apartment;
}
}
这时候建筑有了,施工者有了,那么需要一个监工负责监制:
package com.yitian.builder;
/**
* @Description 监工
* @Author yitianRen
* @Date 2019/9/17 10:51
* @Version 1.0
**/
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void setBuilder(Builder builder) {
this.builder = builder;
}
public Building direct() {
System.out.println("=====工程项目启动=====");
// 第一步,打好地基;
builder.buildBasement();
// 第二步,建造框架、墙体;
builder.buildWall();
// 第三步,封顶;
builder.buildRoof();
System.out.println("=====工程项目竣工=====");
return builder.getBuilding();
}
}
一切都有了,客户这下可以方便的请大家为自己建造房子了,别墅和八层小公寓要建造了!
package com.yitian.builder;
/**
* @Description 客户寻求监工监制住房
* @Author yitianRen
* @Date 2019/9/17 10:53
* @Version 1.0
**/
public class Client {
public static void main(String[] args) {
//招工,建别墅。
Builder builder = new HouseBuilder();
//交给工程总监
Director director = new Director(builder);
System.out.println(director.direct());
//替换施工方,建公寓。
director.setBuilder(new ApartmentBuilder());
System.out.println(director.direct());
/*
=====工程项目启动=====
挖地基,部署管道、线缆,水泥加固,搭建围墙、花园。
搭建木质框架,石膏板封墙并粉饰内外墙。
建造木质屋顶、阁楼,安装烟囱,做好防水。
=====工程项目竣工=====
╱◥███◣
|田|田 田|
╬╬╬╬╬╬╬╬
=====工程项目启动=====
深挖地基,修建地下车库,部署管道、线缆、风道。
搭建多层建筑框架,建造电梯井,钢筋混凝土浇灌。
封顶,部署通风井,做防水层,保温层。
=====工程项目竣工=====
╔═════════╗
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
╚═════════╝
*/
}
}
项目终于竣工了,对于复杂对象的构建,专业的建造团队显然是不可或缺的,尤其是产品内部组件间有某种关联性,构建的顺序性,所以我们把制造工序抽离出来交给了工程总监(Director),而产品各种制造工艺则被多态化交给不同的施工方(Builder)去各显神通,最终达成以相同的构造过程生产不同产品的展现的目的,工序不可乱,工艺不可缺
文章来源 微信公众号 java知音 设计模式