gpt4 book ai didi

java - 对 Joshua Bloch 的 Builder 设计模式的改进?

转载 作者:搜寻专家 更新时间:2023-11-01 04:05:01 25 4
gpt4 key购买 nike

回到 2007 年,我读了一篇关于 Joshua Blochs 的文章,介绍了“构建器模式”以及如何修改它以改善构造函数和 setter 的过度使用,尤其是当一个对象具有大量属性时,其中大部分是可选的。此处 [http://rwhansen.blogspot.com/2007/07/theres-builder-pattern-that-joshua.html] 对这种设计模式进行了简要总结。

我喜欢这个想法,从那以后就一直在使用它。它的问题是,虽然从客户端的角度来看它非常干净且易于使用,但实现它可能会很痛苦!对象中有很多不同的地方引用单个属性,因此创建对象和添加新属性需要花费大量时间。

所以……我有了一个主意。首先是 Joshua Bloch 风格的示例对象:

乔什布洛赫风格:

public class OptionsJoshBlochStyle {

private final String option1;
private final int option2;
// ...other options here <<<<

public String getOption1() {
return option1;
}

public int getOption2() {
return option2;
}

public static class Builder {

private String option1;
private int option2;
// other options here <<<<<

public Builder() {
}

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

public Builder option2(int option2) {
this.option2 = option2;
return this;
}

public OptionsJoshBlochStyle build() {
return new OptionsJoshBlochStyle(this);
}
}

private OptionsJoshBlochStyle(Builder builder) {
this.option1 = builder.option1;
this.option2 = builder.option2;
// other options here <<<<<<
}

public static void main(String[] args) {
OptionsJoshBlochStyle optionsVariation1 = new OptionsJoshBlochStyle.Builder().option1("firefox").option2(1).build();
OptionsJoshBlochStyle optionsVariation2 = new OptionsJoshBlochStyle.Builder().option1("chrome").option2(2).build();
}
}

现在我的“改进”版本:

public class Options {

private String option1;
private int option2;
// ...other options here

public String getOption1() {
return option1;
}

public int getOption2() {
return option2;
}

public static class Builder {

private final Options options;

public Builder() {
this.options = new Options();
}

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

public Builder option2(int option2) {
this.options.option2 = option2;
return this;
}

public Options build() {
return options;//new RequestContext(this);
}
}

private Options() {

}

public static void main(String[] args) {
Options optionsVariation1 = new Options.Builder().option1("firefox").option2(1).build();
Options optionsVariation2 = new Options.Builder().option1("chrome").option2(2).build();

}
}

正如您在我的“改进版本”中看到的那样,我们需要添加有关任何附加属性(或选项,在本例中)的代码的地方减少了 2 个!我能看到的唯一缺点是外部类的实例变量不能是最终的。但是,没有这个类仍然是不可变的。

这种可维护性的改进真的有任何缺点吗?他在嵌套类中重复我没有看到的属性一定是有原因的?

PS:不确定这是否适合 StackOverflow 或属于更主观的问题,如 [programmers.stackexchange.com],所以我提前道歉!

编辑 1:

@irreputable - 在 Java 中有这样的东西吗?由于更改,我仍然不明白这是如何变成线程安全的。我必须按照您的建议研究安全发布。

public class OptionsDelegate {

private final OptionsData data;

private static class OptionsData {
String option1;
int option2;
}

// ...other options here

public String getOption1() {
return data.option1;
}

public int getOption2() {
return data.option2;
}

public static class Builder {

private OptionsData data;

public Builder() {
this.data = new OptionsData();
}

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

public Builder option2(int option2) {
this.data.option2 = option2;
return this;
}

public OptionsDelegate build() {
OptionsDelegate optionsDelegate = new OptionsDelegate(this.data);
this.data = null;
return optionsDelegate;
}
}

private OptionsDelegate(OptionsData data) {
this.data = data;
}

public static void main(String[] args) {
OptionsDelegate optionsVariation1 = new OptionsDelegate.Builder().option1("firefox").option2(1).build();
OptionsDelegate optionsVariation2 = new OptionsDelegate.Builder().option1("chrome").option2(2).build();


}
}

最佳答案

(我期待这个问题被迁移,但无论如何我都会回答 - 答案将被保留。)

你声称这个类仍然是不可变的......但我不认为它是。

Options.Builder builder = new Options.Builder().option1("foo").option2(1);
Options options = builder.build();

builder.option1("changed");
System.out.println(options.getOption1());

请注意,通过一些修改来防止这种情况(在 build() 方法中将 options 设置为 null 以便构建器不能重用)这基本上是 Protocol Buffers 的 Java 实现的模式习惯使用。我相信它现在使用的东西更接近于 Josh 早期的模式。

关于java - 对 Joshua Bloch 的 Builder 设计模式的改进?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6388696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com