头图

写在前面

  • 记录学习设计模式的笔记
  • 提高对设计模式的灵活运用

学习地址

https://www.bilibili.com/vide...

https://www.bilibili.com/vide...

参考文章

http://c.biancheng.net/view/1...

项目源码
https://gitee.com/zhuang-kang/DesignPattern

8,建造者模式

8.1 建造者模式的定义和特点

建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

该模式的主要优点如下:

  1. 封装性好,构建和表示分离。
  2. 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
  3. 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。

其缺点如下:

  1. 产品的组成部分必须相同,这限制了其使用范围。
  2. 如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。

8.2 建造者模式的结构与实现

8.2.1 建造者模式的结构

  1. 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
  2. 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
  3. 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
  4. 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

image

8.2.2 代码实现

House 产品角色

package com.zhuang.builder;

/**
 * @Classname House
 * @Description  产品实现类
 * @Date 2021/3/20 11:49
 * @Created by dell
 */

public class House {
    private String ground;
    private String wall;
    private String roofed;

    public House() {
    }

    public House(String ground, String wall, String roofed) {
        this.ground = ground;
        this.wall = wall;
        this.roofed = roofed;
    }

    public String getGround() {
        return ground;
    }

    public void setGround(String ground) {
        this.ground = ground;
    }

    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{" +
                "ground='" + ground + '\'' +
                ", wall='" + wall + '\'' +
                ", roofed='" + roofed + '\'' +
                '}';
    }
}

HouseBuilder 抽象建造者

package com.zhuang.builder;

/**
 * @Classname HouseBuilder
 * @Description 抽象建造者
 * @Date 2021/3/20 11:49
 * @Created by dell
 */

public abstract class HouseBuilder {
    //创建产品对象
    protected House house = new House();

    //生产产品流程
    public abstract void buildGround();

    public abstract void buildWall();

    public abstract void buildRoofed();

    //返回产品对象
    public House getHouse() {
        return house;
    }
}

HighHouse 具体建造者

package com.zhuang.builder;

/**
 * @Classname HighHouse
 * @Description 具体建造者
 * @Date 2021/3/20 11:51
 * @Created by dell
 */

public class HighHouse extends HouseBuilder {

    @Override
    public void buildGround() {
        house.setGround("100平");
        System.out.println("高楼:打地基");
    }

    @Override
    public void buildWall() {
        house.setWall("50米");
        System.out.println("高楼:砌墙50米");
    }

    @Override
    public void buildRoofed() {
        house.setRoofed("天窗");
        System.out.println("别墅:盖天窗");
    }
}

VillaHouse 具体建造者

package com.zhuang.builder;

/**
 * @Classname VillaHouse
 * @Description  具体建造者
 * @Date 2021/3/20 11:51
 * @Created by dell
 */

public class VillaHouse extends HouseBuilder {

    @Override
    public void buildGround() {
        house.setGround("200平");
        System.out.println("别墅:打地基");
    }

    @Override
    public void buildWall() {
        house.setWall("10米");
        System.out.println("别墅:砌墙10米");
    }

    @Override
    public void buildRoofed() {
        house.setRoofed("天花板");
        System.out.println("别墅:盖天花板");
    }
}

HouseDirector 指挥者

package com.zhuang.builder;

/**
 * @Classname HouseDirector
 * @Description  工程指挥者
 * @Date 2021/3/20 11:50
 * @Created by dell
 */

public class HouseDirector {
    private HouseBuilder houseBuilder;

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

    public House build() {
        houseBuilder.buildGround();
        houseBuilder.buildWall();
        houseBuilder.buildRoofed();
        return houseBuilder.getHouse();
    }
}

Client

package com.zhuang.builder;

/**
 * @Classname Client
 * @Description  产品试用客户端
 * @Date 2021/3/20 11:51
 * @Created by dell
 */

public class Client {
    public static void main(String[] args) {
        House house1 = new HouseDirector(new VillaHouse()).build();
        System.out.println(house1);
        System.out.println("============================================");
        House house2 = new HouseDirector(new HighHouse()).build();
        System.out.println(house2);
    }
}

image

8.3 建造者模式的应用场景

  • 相同的方法,不同的执行顺序,产生不同的结果。
  • 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
  • 产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
  • 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。

9,创建者模式对比

9.1 工厂方法模式VS建造者模式

工厂方法模式注重的是整体对象的创建方式;而建造者模式注重的是部件构建的过程,意在通过一步一步地精确构造创建出一个复杂的对象。

我们举个简单例子来说明两者的差异,如要制造一个超人,如果使用工厂方法模式,直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人;而如果使用建造者模式,则需要组装手、头、脚、躯干等部分,然后再把内裤外穿,于是一个超人就诞生了。

9.2 抽象工厂模式VS建造者模式

抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式则是不需要关心构建过程,只关心什么产品由什么工厂生产即可。

建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品。

如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车。

  • 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象
  • 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
  • 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
  • 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。

写在最后

  • 如果我的文章对你有用,请给我点个👍,感谢你😊!
  • 有问题,欢迎在评论区指出!💪

康小庄
12 声望6 粉丝

代码不停,思考不止.