设计模式之建造者模式

思路多态下,建造不同类型的“建筑”,通过第三方监工监制,用户调用监工即可

场景之一:盖房子举例,房子本身有很多个组成部分,各组件息息相关缺一不可,否则房倒屋塌。而其构造过程也是相当复杂的,但大家不必担心,为响应我们简约直观的一贯宗旨,这里只将其简化拆分成地基、墙体、屋顶三部分,首先来看建筑物类。

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知音  设计模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值