建造者的消费者或功能

Consumer or Function for builder

我写了一个构建器来设置一些配置。建造者的方法之一是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) 不起作用,因为此方法不是静态的。

有什么想法吗?

我找到了解决方案,但我对此不是很满意。我添加了带有构建器参数的方法的静态版本(感谢 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);
}

我看不出有什么理由在这里传递函数。简单地提取通用代码应该已经保存了您的重复代码。而且,恕我直言,它更容易准备和理解

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();
}