非官方解读建造者模式

建造者模式,又称为生成器模式,将复杂对象的构建过程抽象.使不同的实现方法可以构造出不同的对象,内部构建过程透明.有四个角色,这四个角色并不是必然存在的,因为设计模式本就是大而无形,有的只是个思想.
产品角色(Product), 构建出的结果,具体的产品对象
抽象建造者(Builder), 创建一个产品对象的各个部件,指定的接口/抽象类
具体建造者(ConcreteBuilder), 实现接口构建和组装各个部件
指挥者(Director),构建一个使用抽象建造者的对象,用于创建复杂对象,隔离生成过程,控制产品对象生产过程

作者是个二吊子,如果描述有误请指出.


使用场景

我们在构建一个产品时(这时候就有了产品角色),这个产品可能有不同的行为过程,而这些过程我们不想知道,所以我们就有了抽象建造者,抽象建造者是规范了行为,将行为进行抽象.没有具体实现.当我们需要建造一个产品时,我们需要有具体的实现类(具体建造者).由它来实现抽象建造者中定义的各种行为.进行自定义实现.但是以上三个角色虽然有依赖关系存在.但是却没有统一的入口,如果我们由抽象建造者进行多态来进行调用,那么我们的行为规范可能就会受到破坏.因为我们的行为往往都是具有顺序性的.这时候就引入了指挥者,由它来控制进度和顺序,以及提供统一对外接口.

举个扯淡的例子, .就像建房子,我们要知道进度或者建一个房子,虽然你可以直接去找搬砖工程师,刷墙工程师,抬杠工程师.
你来进行协调让他们搞.但是你这样只能建一个房子,你又不专业,这样可能就搞出了豆腐渣.
那么我们就需要来进行规范化.这个时候一个脑回路清奇的哥们就说,我们出个搬砖手册吧,上面写我们谁该干嘛,于是就有了搬砖手册(抽象建造者),
但是这个只是一个规范,我们要实施还是不一样的,搬砖工程师就具体定义了我们该怎么搬砖,他们实现了一个具体的行为规范,抬杠工程师定义了该怎么抬杠,刷墙的定义了具体怎么喷.这些具体定义都来自手册(抽象建造者).这些具体的行为规范就成了工程师的自我修养(具体建造者).
但是这么搞还是不对劲啊,这tm 我才搬了砖过来还没贴,这个刷墙的哥们就喷上了,这顺序不低啊,抬杠的哥们发现钢筋抬过来了,这搬砖的把墙都砌好了.这谁顶得住,钢筋还没用墙就有了.墙还没砌,刷墙就开始喷了.一切都是这么不可思议.
于是乎,工地又招了一个包工头,这哥们久经沙场知道该怎么砌房子怎么跟客户扯皮.于是他负责协调和对外.让搬砖的先把砖拿过来,抬杠的把钢筋整到位.然后砌墙,刷墙.大家就这么干起来了.房子也成了.

建造者模式雏形

uml图
初期建造者

我们最开始的样子,考虑了房子的估计行为顺序,但是我们只是定义了行为和行为的顺序执行,由具体实现来做具体的工作,比如CommonHouse 可以理解为具体建造者,这个也可以理解为一个工程队,每个工程队都可以干这些事情,但是搞得过程是五花八门,有些杀鸡祭天的有些杀工程师的.这样子我们在用的时候直接多态用组合或者聚合都可以使用.但是这样扩展性不是很好,我们新加一个具体建造者,也就是工程队,那么我们在客户端使用的时候就会用到,如果后边要去掉一个,就很五花八门了.由此,这个做法是不成熟的,只能是小公司做派,管理制度不完善,拍脑袋想事情.

/**
 * @Description: 最初版的抽象建造者
 * @Author: gaofan
 * @Date: 2020/3/21 15:36
 * @Copyright: 2020 www.withu.top Inc. All rights reserved.
 **/
public abstract class AbstractHouse {

    // 打地基
    public abstract void buildBasic();
    // 砌墙
    public abstract void buildWall();
    // 封底
    public abstract void roofed();

    public void build(){
        buildBasic();
        buildWall();
        roofed();
    }
}
/**
 * @Description: 好理解,易操作,增加了耦合性.把产品和行为过程封装在一起
 * @Author: gaofan
 * @Date: 2020/3/21 15:38
 * @Copyright: 2020 www.withu.top Inc. All rights reserved.
 **/
public class CommonHouse extends AbstractHouse {
    @Override
    public void buildBasic() {
        System.out.println("普通房子打地基");
    }

    @Override
    public void buildWall() {
        System.out.println("普通房子砌墙");
    }

    @Override
    public void roofed() {
        System.out.println("普通房子封顶");
    }
}
/**
 * @Description: TODO
 * @Author: gaofan
 * @Date: 2020/3/21 15:39
 * @Copyright: 2020 www.withu.top Inc. All rights reserved.
 **/
public class Client {

    public static void main(String [] args){
        AbstractHouse houseBuild = new CommonHouse();
        houseBuild.build();
    }
}

类型: 初期建造者的雏形
原理: 通过产品和行为整合到一起实现的,分类不是很细化,如果后期有增加或者修改会比较不合理,单一性不好,我从这里看到了模板模式的咸味了.

建造者模式

在抽象的基础上越走越远.将产品与行为进行划分.初期的建造者只注重了行为.虽然建造者模式其主要的限定操作是行为,但是这并不代表能抛弃产品.而建造者模式对他们进行划分.
uml图
在这里插入图片描述

这就是比较完善的一个体制,各司其职,是对单一性原则进行的反复阐述.如不懂,可以借鉴开始的那个举例,如果看完了还是不懂,那多半是博主菜鸡没写好,请留言备注,轻喷

/**
 * @Description: 抽象建造者
 * @Author: gaofan
 * @Date: 2020/3/21 15:56
 * @Copyright: 2020 www.withu.top Inc. All rights reserved.
 **/
public abstract class HouseBuilder {

    protected House house = new House();

    public abstract void buildBasic();

    public abstract void buildWall();

    public abstract void roofed();

    public House build(){
        return house;
    }
}
/**
 * @Description: 具体建造者
 * @Author: gaofan
 * @Date: 2020/3/21 15:59
 * @Copyright: 2020 www.withu.top Inc. All rights reserved.
 **/
public class HightBuilding extends HouseBuilder {

    @Override
    public void buildBasic() {
        super.house.setBasic("高层房子打地基-50米");
        System.out.println("高层房子打地基-50米");
    }

    @Override
    public void buildWall() {
        super.house.setWall("高层房子砌墙-100cm");
        System.out.println("高层房子砌墙-100cm");
    }

    @Override
    public void roofed() {
        super.house.setRoofed("高层房子封底");
        System.out.println("普通房子封底");
    }
}
/**
 * @Description: 具体建造者
 * @Author: gaofan
 * @Date: 2020/3/21 15:58
 * @Copyright: 2020 www.withu.top Inc. All rights reserved.
 **/
public class CommonHouse extends HouseBuilder {

    @Override
    public void buildBasic() {
        System.out.println("普通房子打地基-5米");
    }

    @Override
    public void buildWall() {
        System.out.println("普通房子砌墙-10cm");
    }

    @Override
    public void roofed() {
        System.out.println("普通房子封底");
    }
}
/**
 * @Description: 产品
 * @Author: gaofan
 * @Date: 2020/3/21 15:55
 * @Copyright: 2020 www.withu.top Inc. All rights reserved.
 **/
public class House {

    private String basic;

    private String wall;

    private String roofed;

    public House() {}

    public String getBasic() {
        return basic;
    }

    public void setBasic(String basic) {
        this.basic = basic;
    }

    public String getWall() {
        return wall;
    }

    public void setWall(String wall) {
        this.wall = wall;
    }

    public String getRoofed() {
        return roofed;
    }

    public void setRoofed(String roofed) {
        this.roofed = roofed;
    }

    @Override
    public String toString() {
        return "House{" +
                "basic='" + basic + '\'' +
                ", wall='" + wall + '\'' +
                ", roofed='" + roofed + '\'' +
                '}';
    }
}
/**
 * @Description: 指挥者
 * @Author: gaofan
 * @Date: 2020/3/21 16:01
 * @Copyright: 2020 www.withu.top Inc. All rights reserved.
 **/
public class HouseDirector {

    HouseBuilder houseBuilder = null;

    public HouseDirector(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }

    public void setHouseBuilder(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }

    // 如何建造房子,指挥者处理
    public House buildHouse(){
        houseBuilder.buildBasic();
        houseBuilder.buildWall();
        houseBuilder.roofed();
        return houseBuilder.build();
    }
}
/**
 * @Description: TODO
 * @Author: gaofan
 * @Date: 2020/3/21 16:06
 * @Copyright: 2020 www.withu.top Inc. All rights reserved.
 **/
public class Client {

    public static void main(String [] args){
        CommonHouse commonHouse = new CommonHouse();
        HouseDirector director = new HouseDirector(commonHouse);
        House house = director.buildHouse();
        System.out.println(house.toString());
    }
}

类型: 建造者模式
原理: 将行为和产品区分,属于创建型设计模式,目的是为了创建对象实例.但是个人理解建造者模式注重行为的整合,具体建造者类提供具体实现,然后指挥者进行拼装分配,从而达到组装对象实例的目的.与抽象工厂模式不同的是,抽象工厂模式返回一类产品,以产品划分.这里是根据行为整合的一种方式,说像也像,说不像也不像.感觉学了设计模式也学会了什么叫 似是而非…
缺点: 编码会增多


本文借鉴尚硅谷Java设计模式,韩顺平图解java,传送门

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值