Java (Fluent)Builder模式的继承

Fluent风格的代码十分流行,应用在Builder模式中也很常见,下面是一个简单的例子:

public class FluentBuilder {
    private String param1;
    private String param2;
    
    public FluentBuilder setParam1(String param1){
        this.param1 = param1;
        return this;
    }
    
    public FluentBuilder setParam2(String param2){
        this.param2 = param2;
        return this;
    }
    
    public String build(){
        return param1 + param2;
    }
}

使用起来很简洁:

        String result = new FluentBuilder()
            .setParam1("1")
            .setParam2("2")
            .build();

有时候对于具有相关对象的构造,需要复用builder代码,这时会遇到一些语法上的困难。

  • 子类Builder:
public class SubFluentBuilder extends FluentBuilder {
    private String param3;
    
    public SubFluentBuilder setParam3(String param3){
        this.param3 = param3;
        return this;
    } 
}
  • 如果先调用子类方法,再调父类方法,则不会有问题
        String result = new SubFluentBuilder()
                .setParam3("3")
                .setParam1("1")
                .setParam2("2")
                .build();
  • 但是父类方法在子类之前,则子类方法不再可见:
        String result = new SubFluentBuilder()
                .setParam1("1")
                .setParam2("2")
                .setParam3("3")//编译错误,无法找到该方法
                .build();
  • 原因在于 SubFluentBuilder.setParam2() 返回的是 FluentBuilder, 而它是不具备子类方法的。

这里有两个解决方案

第一种是通过泛型来获得子类类型,返回this强制转换成子类。 这时无论子类、父类都返回子类builder,所有方法可用。
public class GenericBuilder> {
    private String param1;
    private String param2;
    
    public T setParam1(String param1){
        this.param1 = param1;
        return (T)this;
    }
    
    public T setParam2(String param2){
        this.param2 = param2;
        return (T)this;
    }
    
    public String build(){
        return param1 + param2;
    }
}
public class SubGenericBuilder extends GenericBuilder {
    private String param3;
    
    public SubGenericBuilder setParam3(String param3){
        this.param3 = param3;
        return this;
    } 
}
第二种方案就是重写所有父类方法,使之返回子类类型, JDK中StringBuilder/StringBuffer就是这样实现的 :
public class SubFluentBuilder2 extends FluentBuilder {
    private String param3;
    
    public SubFluentBuilder2 setParam1(String param1){
        super.setParam1(param1);
        return this;
    }
    
    public SubFluentBuilder2 setParam2(String param2){
        super.setParam2(param2);
        return this;
    }
    
    public SubFluentBuilder2 setParam3(String param3){
        this.param3 = param3;
        return this;
    } 

你可能感兴趣的:(Java (Fluent)Builder模式的继承)