学习总结

  1. 属于对象创建模式。
  2. 与工厂的区别在于工厂更关心得到产品,建造者更重视建造过程。

动机 Motivation

  1. 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一-定的算法构成;由于需求的变化,这个复
    杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一-起的算法却相对稳定。
  2. 如何应对这种变化?如何提供一种“封装机制"来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?

要点总结

  1. Builder模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化.
  2. 变化点在哪里,封装哪里——Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
  3. 在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++ Vs. C#)。

应用场景

  1. https://docs.spring.io/spring-boot/docs/2.0.x/api/org/springframework/boot/jdbc/DataSourceBuilder.html

UML

代码示例

1. 手工打造

package com.jerry.designpattern.builder.demo1;

/**
 * @author jerryjin
 * @Classname Hero
 * @Description name、age 为必填项目
 * @Date 2021-04-08 16:19
 */
public class Hero {
    private String name;
    private int age;
    private String wquipment ;
    private double money ;
    
    public static Hero.Builder builder(String name, int age){
        return new Builder(name, age);
    }

    private Hero(Builder builder) {
        this.name = builder.name;
        this.age = builder.age;
        this.wquipment = builder.wquipment;
        this.money = builder.money;
    }    

    public static class Builder{
        
        private final String name;/*必填*/
        private final int age;/*必填*/
        private String wquipment ;
        private double money ;

        public Builder(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public Builder wquipment(String wquipment){
            this.wquipment = wquipment;
            return this;
        }

        public Builder money(double money){
            this.money = money;
            return this;
        }
		// 建造...
        public Hero build(){
            return new Hero(this);
        }
    }

    @Override
    public String toString() {
        return "英雄:" + name + ", 年龄:" + age + ", 装备:" + wquipment + ", 银两:" + money +"万";
    }
}

public class BuilderPatternDemo {

    public static void main(String[] args) {
        Hero hero = Hero.builder("华安", 18)
                .wquipment("无头枪")
                .money(100)
                .build();

        System.out.println(hero);
    }
    
}

2. 使用 lombok的 @Builder

2.1. 默认值

@Builder
public class Hero {
    @Builder.Default
    private String name = "张三";
    @Builder.Default
    private Integer age = 18;
    private String wquipment ;
    private Double money ;
    @Singular
    private List<Hero> friends;
    
    @Override
    public String toString() {
        return "英雄:" + name + ", 年龄:" + age + ", 装备:" + wquipment + ", 银两:" + money +"万";
    }
}

2.2. 必填项

@Builder(builderMethodName ="innerBuilder")
public class Hero2 {

    private String name;
    private Integer age;
    private String wquipment ;
    private Double money ;
    @Singular
    private List<Hero2> friends;

    public static Hero2Builder builder(String name, Integer age){
        return innerBuilder().name(name).age(age);
    }

    @Override
    public String toString() {
        return "英雄:" + name + ", 年龄:" + age + ", 装备:" + wquipment + ", 银两:" + money +"万";
    }
}

2.3. Demo

public class BuilderPatternDemo {

    public static void main(String[] args) {
        Hero hero = Hero.builder()
                .name("华安")
                .age(20)
                .wquipment("无头枪")
                .money(100.0)
                .build();
        System.out.println(hero);

        System.out.println(Hero.builder().wquipment("无头枪").money(100.0).build());
        System.out.println(Hero2.builder("李逵", 18).wquipment("板斧").money(100.0).build());
    }
    
}

参考资料

23种设计模式第四讲:建造者(构建器)模式

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐