# 建造者模式

# 简介

创建型模式,用于构建复杂且易变化对象。先来个简化版的,也是很多框架中采用的一种,让代码优雅起来。

# 示例1

public class JwtToken {
    private String header;
    private String body;
    private String sign;

    public JwtToken header(String header){
        this.header = header;
        return this;
    }

    public JwtToken body(String body){
        this.body = body;
        return this;
    }

    public JwtToken sign(String sign){
        this.sign = sign;
        return this;
    }


    public String getHeader() {
        return header;
    }

    public String getBody() {
        return body;
    }

    public String getSign() {
        return sign;
    }
}

# 调用

@Test
public void t1() {
    JwtToken jwtToken = new JwtToken().header("header").body("body").sign("sign");
    System.out.println(String.format("%s,%s,%s", jwtToken.getHeader(), jwtToken.getBody(), jwtToken.getSign()));
}

# 示例2

public class JwtToken2 {
    private String header;
    private String body;
    private String sign;

    public static JwtTokenBuilder builder() {
        return new JwtTokenBuilder();
    }

    private JwtToken2(String header, String body, String sign) {
        this.header = header;
        this.body = body;
        this.sign = sign;
    }

    public static class JwtTokenBuilder {
        private String header;
        private String body;
        private String sign;

        public JwtTokenBuilder header(String header) {
            this.header = header;
            return this;
        }

        public JwtTokenBuilder body(String body) {
            this.body = body;
            return this;
        }

        public JwtTokenBuilder sign(String sign) {
            this.sign = sign;
            return this;
        }

        public JwtToken2 build() {
            return new JwtToken2(this.header, this.body, this.sign);
        }
    }

    public String getHeader() {
        return header;
    }

    public String getBody() {
        return body;
    }

    public String getSign() {
        return sign;
    }
}

# 调用

@Test
public void t2() {
    JwtToken2 jwtToken = JwtToken2.builder().header("header").body("body").sign("sign").build();
    System.out.println(String.format("%s,%s,%s", jwtToken.getHeader(), jwtToken.getBody(), jwtToken.getSign()));
}

# 支持继承

如果直接使用继承,在builder字段时如果先builder父类的字段,再builder子类字段时编译器会报错,因为返回的是父类对象引用,可以使用泛型获得子类类型,在父类返回this时强转为子类类型。

public class BasicBuilder<T extends BasicBuilder<T>> {
    private String field1;
    private String field2;

    public T field1(String field1) {
        this.field1 = field1;
        return self();
    }

    public T field2(String field2) {
        this.field2 = field2;
        return self();
    }

    private T self(){
        return (T) this;
    }

    public String getField1() {
        return field1;
    }

    public String getField2() {
        return field2;
    }

}

public class SubBuilder extends BasicBuilder<SubBuilder> {
    private String field3;
    private String field4;

    public SubBuilder field3(String field3) {
        this.field3 = field3;
        return this;
    }

    public SubBuilder field4(String field4) {
        this.field4 = field4;
        return this;
    }

    public String getField3() {
        return field3;
    }

    public String getField4() {
        return field4;
    }
}

# 调用

@Test
public void t3() {
    SubBuilder builder = new SubBuilder().field1("field1").field3("field3").field4("field4").field2("field2");
    System.out.println(String.format("%s,%s,%s,%s", builder.getField1(), builder.getField2(), builder.getField3(), builder.getField4()));
}

# 支持继承2

上面那种继承实现方式,只能支持一个层级的继承,多层继承无法实现,下面这种方式可以多层继承,实现简单,缺点是代码重复率较高。


public class BasicBuilder2{
    private String field1;
    private String field2;

    public BasicBuilder2 field1(String field1) {
        this.field1 = field1;
        return this;
    }

    public BasicBuilder2 field2(String field2) {
        this.field2 = field2;
        return this;
    }

    public String getField1() {
        return field1;
    }

    public String getField2() {
        return field2;
    }
}

public class SubBuilder2 extends BasicBuilder {
    private String field3;
    private String field4;

    @Override
    public SubBuilder2 field1(String field1) {
        super.field1(field1);
        return this;
    }

    @Override
    public SubBuilder2 field2(String field2) {
        super.field2(field2);
        return this;
    }

    public SubBuilder2 field3(String field3) {
        this.field3 = field3;
        return this;
    }

    public SubBuilder2 field4(String field4) {
        this.field4 = field4;
        return this;
    }

    public String getField3() {
        return field3;
    }

    public String getField4() {
        return field4;
    }
}

public class SubSubBuilder2 extends SubBuilder2 {
    private String field5;
    private String field6;

    @Override
    public SubSubBuilder2 field1(String field1) {
        super.field1(field1);
        return this;
    }

    @Override
    public SubSubBuilder2 field2(String field2) {
        super.field2(field2);
        return this;
    }

    @Override
    public SubSubBuilder2 field3(String field3) {
        super.field3(field3);
        return this;
    }

    @Override
    public SubSubBuilder2 field4(String field4) {
        super.field4(field4);
        return this;
    }

    public SubSubBuilder2 field5(String field5) {
        this.field5 = field5;
        return this;
    }

    public SubSubBuilder2 field6(String field6) {
        this.field6 = field6;
        return this;
    }

    public String getField5() {
        return field5;
    }

    public String getField6() {
        return field6;
    }
}

# 调用

@Test
public void t4() {
    SubSubBuilder2 builder = new SubSubBuilder2().field1("field1").field6("field6").field3("field3").field4("field4").field2("field2").field5("field5");
    System.out.println(String.format("%s,%s,%s,%s,%s,%s", builder.getField1(), builder.getField2(), builder.getField3(),
            builder.getField4(), builder.getField5(), builder.getField6()));
}