构建者的消费者或功能

时间:2017-06-15 11:04:42

标签: java builder method-reference

我写了一个构建器来设置一些配置。构建器的一种方法是edit(BusinessObject)。现在我得到了导致相同配置的要求,除了用copy(BusinessObject)替换这个方法。所以当前的实现将是:

public Config editObject(BusinessObject object) {
    return new ConfigBuilder()
        .config1(p1)
        .config2(p2)
        .config3(p3)
        ...
        .edit(object)
        .build();
}

public Config copyObject(BusinessObject object) {
    return new ConfigBuilder()
        .config1(p1)
        .config2(p2)
        .config3(p3)
        ...
        .copy(object)
        .build();
}

class ConfigBuilder {

    ConfigBuilder edit(BusinessObject o) {
        // prepare some settings
        return this;
    }

    ConfigBuilder copy(BusinessObject o) {
        // prepare some other settings
        return this;
    }
}

为了避免重复的代码(除了这一行,其他一切都是相同的)我想将它提取到一个带有Function<BusinessObject, ConfigBuilder> prepare等附加参数的新方法。

但我一直坚持如何解决它。构建器实例将在editObject / copyObject的范围之外创建,因此editOrCopy(object, ConfigBuilder::copy)不起作用,因为此方法不是静态的。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

我认为没有理由在这里传递函数。简单地提取公共代码应该已经保存了重复的代码。并且,imho,更容易准备和理解

private ConfigBuilder commonBuilder() {
    return new ConfigBuilder()
        .config1(p1)
        .config2(p2)
        .config3(p3);
}

public Config editObject(BusinessObject object) {
    return commonBuilder().edit(object).build();
}

public Config copyObject(BusinessObject object) {
    return commonBuilder().copy(object).build();
}

答案 1 :(得分:0)

我得到了一个解决方案,但我对此并不满意。我使用构建器参数添加了方法的静态版本(感谢 Holger :现在我很高兴,不需要静态方法):

class ConfigBuilder

    ConfigBuilder edit(BusinessObject o) {
        // prepare some settings
        return this;
    }

    ConfigBuilder copy(BusinessObject o) {
        // prepare some other settings
        return this;
    }
}

现在我可以将方法引用传递给新创建的方法:

private Config modifyObject(BusinessObject object, BiFunction<ConfigBuilder, BusinessObject, ConfigBuilder> modify) {
    return modify.apply(new ConfigBuilder(), object)
        .config1(p1)
        .config2(p2)
        .config3(p3)
        ...
        .build();
}

问题中提到了这个问题

public Config editObject(BusinessObject object) {
    return modifyObject(object, ConfigBuilder::edit);
}

public Config copyObject(BusinessObject object) {
    return modifyObject(object, ConfigBuilder::copy);
}