Java设计模式(五)创建型- 建造者Builder模式(史上最全建造者模式常规简化链式写法)与使用场景以及优缺点

  1. 建造者Builder模式

建造者模式是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。用户只需指定需要建造的类型就可以获得对象,建造过程及细节不需要了解。

建造者(Builder)模式包含如下角色:

  • 抽象建造者类(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的部件对象的创建。
  • 具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供产品的实例。
  • 产品类(Product):要创建的复杂对象。
  • 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建。

1.1 常规写法

//产品类 电脑
@Data
public class Computer {
    private String motherboard;
    private String cpu;
    private String memory;
    private String disk;
    private String gpu;
    private String power;
    private String heatSink;
    private String chassis;
}
// 抽象 builder类(接口) 组装电脑
public interface ComputerBuilder { 
    Computer computer = new Computer();
    void buildMotherboard();
    void buildCpu();
    void buildMemory();
    void buildDisk();
    void buildGpu();
    void buildHeatSink();
    void buildPower();
    void buildChassis();
    Computer build();
}
// 具体 builder类 华硕ROG全家桶电脑(手动狗头)
public class AsusComputerBuilder implements ComputerBuilder {
    @Override 
    public void buildMotherboard() {
        computer.setMotherboard("Extreme主板");
    }
    @Override
    public void buildCpu() {
        computer.setCpu("Inter 12900KS");
    }
    @Override
    public void buildMemory() {
        computer.setMemory("芝奇幻峰戟 16G*2");
    }
    @Override
    public void buildDisk() {
        computer.setDisk("三星980Pro 2T");
    }
    @Override
    public void buildGpu() {
        computer.setGpu("华硕3090Ti 水猛禽");
    }
    @Override
    public void buildHeatSink() {
        computer.setHeatSink("龙神二代一体式水冷");
    }
    @Override
    public void buildPower() {
        computer.setPower("雷神二代1200W");
    }
    @Override
    public void buildChassis() {
        computer.setChassis("太阳神机箱");
    }
    @Override
    public Computer build() {
        return computer;
    }
}
// 指挥者类 指挥该组装什么电脑
@AllArgsConstructor
public class ComputerDirector {
    private ComputerBuilder computerBuilder;
    public Computer construct() {
        computerBuilder.buildMotherboard();
        computerBuilder.buildCpu();
        computerBuilder.buildMemory();
        computerBuilder.buildDisk();
        computerBuilder.buildGpu();
        computerBuilder.buildHeatSink();
        computerBuilder.buildPower();
        computerBuilder.buildChassis();
        return computerBuilder.build();
    }
}
   // 测试
    public static void main(String[] args) {
        ComputerDirector computerDirector = new ComputerDirector(new AsusComputerBuilder());
        // Computer(motherboard=Extreme主板, cpu=Inter 12900KS, memory=芝奇幻峰戟 16G*2, disk=三星980Pro 2T, gpu=华硕3090Ti 水猛禽, power=雷神二代1200W, heatSink=龙神二代一体式水冷, chassis=太阳神机箱)
        System.out.println(computerDirector.construct());
    }

上面示例是建造者模式的常规用法,指挥者类ComputerDirector在建造者模式中具有很重要的作用,它用于指导具体构建者如何构建产品,控制调用先后次序,并向调用者返回完整的产品类,但是有些情况下需要简化系统结构,可以把指挥者类和抽象建造者进行结合,于是就有了下面的简化写法。

1.2 简化写法

// 把指挥者类和抽象建造者合在一起的简化建造者类
public class SimpleComputerBuilder {
    private Computer computer = new Computer();
    public void buildMotherBoard(String motherBoard){
        computer.setMotherboard(motherBoard);
    }
    public void buildCpu(String cpu){
        computer.setCpu(cpu);
    }
    public void buildMemory(String memory){
        computer.setMemory(memory);
    }
    public void buildDisk(String disk){
        computer.setDisk(disk);
    }
    public void buildGpu(String gpu){
        computer.setGpu(gpu);
    }
    public void buildPower(String power){
        computer.setPower(power);
    }
    public void buildHeatSink(String heatSink){
        computer.setHeatSink(heatSink);
    }
    public void buildChassis(String chassis){
        computer.setChassis(chassis);
    }
    public Computer build(){
        return computer;
    }
}
    // 测试
    public static void main(String[] args) {
        SimpleComputerBuilder simpleComputerBuilder = new SimpleComputerBuilder();
        simpleComputerBuilder.buildMotherBoard("Extreme主板");
        simpleComputerBuilder.buildCpu("Inter 12900K");
        simpleComputerBuilder.buildMemory("芝奇幻峰戟 16G*2");
        simpleComputerBuilder.buildDisk("三星980Pro 2T");
        simpleComputerBuilder.buildGpu("华硕3090Ti 水猛禽");
        simpleComputerBuilder.buildPower("雷神二代1200W");
        simpleComputerBuilder.buildHeatSink("龙神二代一体式水冷");
        simpleComputerBuilder.buildChassis("太阳神机箱");
        // Computer(motherboard=Extreme主板, cpu=Inter 12900K, memory=芝奇幻峰戟 16G*2, disk=三星980Pro 2T, gpu=华硕3090Ti 水猛禽, power=雷神二代1200W, heatSink=龙神二代一体式水冷, chassis=太阳神机箱)
        System.out.println(simpleComputerBuilder.build());
    }

可以看到,对比常规写法,这样写确实简化了系统结构,但同时也加重了建造者类的职责,也不是太符合单一职责原则,如果construct() 过于复杂,建议还是封装到 Director 中。

1.3 链式写法

// 链式写法建造者类
public class SimpleComputerBuilder {
    private Computer computer = new Computer();
    public SimpleComputerBuilder buildMotherBoard(String motherBoard){
        computer.setMotherboard(motherBoard);
        return this;
    }
    public SimpleComputerBuilder buildCpu(String cpu){
        computer.setCpu(cpu);
        return this;
    }
    public SimpleComputerBuilder buildMemory(String memory){
        computer.setMemory(memory);
        return this;
    }
    public SimpleComputerBuilder buildDisk(String disk){
        computer.setDisk(disk);
        return this;
    }
    public SimpleComputerBuilder buildGpu(String gpu){
        computer.setGpu(gpu);
        return this;
    }
    public SimpleComputerBuilder buildPower(String power){
        computer.setPower(power);
        return this;
    }
    public SimpleComputerBuilder buildHeatSink(String heatSink){
        computer.setHeatSink(heatSink);
        return this;
    }
    public SimpleComputerBuilder buildChassis(String chassis){
        computer.setChassis(chassis);
        return this;
    }
    public Computer build(){
        return computer;
    }
}
    // 测试
    public static void main(String[] args) {
        Computer asusComputer = new SimpleComputerBuilder().buildMotherBoard("Extreme主板")
            .buildCpu("Inter 12900K")
            .buildMemory("芝奇幻峰戟 16G*2")
            .buildDisk("三星980Pro 2T")
            .buildGpu("华硕3090Ti 水猛禽")
            .buildPower("雷神二代1200W")
            .buildHeatSink("龙神二代一体式水冷")
            .buildChassis("太阳神机箱").build();
        System.out.println(asusComputer);
    }

可以看到,其实链式写法与普通写法的区别并不大,只是在建造者类组装部件的时候,同时将建造者类返回即可,使用链式写法使用起来更方便,某种程度上也可以提高开发效率。从软件设计上,对程序员的要求比较高。比较常见的mybatis-plus中的条件构造器就是使用的这种链式写法。

1.4 总结

适用场景:

  • 适用于创建对象需要很多步骤,但是步骤顺序不一定固定。
  • 如果一个对象有非常复杂的内部结构(属性),把复杂对象的创建和使用进行分离。

优点:

  • 封装性好,创建和使用分离。
  • 扩展性好,建造类之间独立、一定程度上解耦。

缺点:

  • 产生多余的Builder对象。
  • 产品内部发生变化,建造者都要修改,成本较大。

与工厂模式的区别:

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

与抽象工厂模式的区别:

  • 抽象工厂模式实现对产品族的创建,一个产品族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式则是不需要关心构建过程,只关心什么产品由什么工厂生产即可。
  • 建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品。
  • 建造者模式所有函数加到一起才能生成一个对象,抽象工厂一个函数生成一个对象
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
建造者模式是一种创建设计模式,它可以将复杂对象的创建过程分解成多个简单对象的创建过程,从而简化对象的创建过程。 建造者模式适用于以下场景: 1. 需要创建复杂对象,且该对象由多个组成部分构成,且这些组成部分的创建顺序或逻辑固定不变。 2. 需要创建的对象具有可变性,即需要创建多个不同的对象,但它们的组成部分大部分相同。 3. 需要在不同的场景创建不同的对象,但是这些对象的创建流程相对固定。 下面是一个示例 Java 代码,演示如何使用建造者模式创建一个复杂对象——计算机: ``` public class Computer { private String cpu; private String gpu; private String memory; private String hardDisk; private String monitor; private String keyboard; private String mouse; private Computer(ComputerBuilder builder) { this.cpu = builder.cpu; this.gpu = builder.gpu; this.memory = builder.memory; this.hardDisk = builder.hardDisk; this.monitor = builder.monitor; this.keyboard = builder.keyboard; this.mouse = builder.mouse; } public String getCpu() { return cpu; } public String getGpu() { return gpu; } public String getMemory() { return memory; } public String getHardDisk() { return hardDisk; } public String getMonitor() { return monitor; } public String getKeyboard() { return keyboard; } public String getMouse() { return mouse; } public static class ComputerBuilder { private String cpu; private String gpu; private String memory; private String hardDisk; private String monitor; private String keyboard; private String mouse; public ComputerBuilder setCpu(String cpu) { this.cpu = cpu; return this; } public ComputerBuilder setGpu(String gpu) { this.gpu = gpu; return this; } public ComputerBuilder setMemory(String memory) { this.memory = memory; return this; } public ComputerBuilder setHardDisk(String hardDisk) { this.hardDisk = hardDisk; return this; } public ComputerBuilder setMonitor(String monitor) { this.monitor = monitor; return this; } public ComputerBuilder setKeyboard(String keyboard) { this.keyboard = keyboard; return this; } public ComputerBuilder setMouse(String mouse) { this.mouse = mouse; return this; } public Computer build() { return new Computer(this); } } } // 使用建造者模式创建计算机对象 Computer computer = new Computer.ComputerBuilder() .setCpu("Intel Core i7-9700K") .setGpu("NVIDIA GeForce RTX 2080 Ti") .setMemory("32GB DDR4") .setHardDisk("1TB NVMe SSD") .setMonitor("Dell U3419W") .setKeyboard("Logitech G Pro X") .setMouse("Logitech G Pro Wireless") .build(); ``` 在上面的示例中,我们使用了一个静态内部类 `ComputerBuilder` 来创建计算机对象。在 `ComputerBuilder` 中,我们定义了多个方法来设置计算机的组成部分。在最后,我们使用 `build()` 方法来创建计算机对象。这样就可以实现快速创建具有可变性的、复杂的计算机对象了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘了个刘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值