gpt4 book ai didi

java - 使 Bloch 的构建器模式线程安全 : Rechecking necessary in enclosing constructor if NEVER invalid?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:35:45 24 4
gpt4 key购买 nike

最近学习了Joshua Bloch's builder pattern用于创建具有许多可选字段的对象。多年来我一直在使用类似的东西,但在 Bloch 的书向我建议之前从未使用过内部类。我喜欢它。

我知道另一个线程可能会在实际构建之前更改构建器的配置(使用 build()),这样可能有必要重新验证封闭的构造函数中的所有值类(class)。下面是一个构建器类的示例,它可以选择性地重新验证其数据。

所以我的问题是:假设这是一个足够健壮的设计,当所有值都有默认值时——知道这个类是使用默认值的糟糕选择——并且当每次设置尝试都经过验证时,这是否重新- 需要检查吗?尽管它可能不同,但它永远不会无效。对吗?

(尽管这种设计易于管理,但由于可能需要重新验证,它肯定会变得复杂。老实说,我从不使用多线程,但我不想让使用多线程的人无法使用我的库。)

感谢您的任何建议。

/**
<P><CODE>java ReverifyBuilderInEnclosingCnstrXmpl</CODE></P>
**/
public class ReverifyBuilderInEnclosingCnstrXmpl {
public static final void main(String[] igno_red) {

//Don't reverify
ReverifyBuilderInEnclosingCnstrXmpl rvbdx = new ReverifyBuilderInEnclosingCnstrXmpl.Cfg().
name("Big Bird").age(6).build();

System.out.println(rvbdx.sName);
System.out.println(rvbdx.iAge);

//Do reverify
rvbdx = new ReverifyBuilderInEnclosingCnstrXmpl.Cfg().
reverifyInEnclosing().
name("Big Bird").age(6).build();
}

public final String sName;
public final int iAge;
/**
<P>Create a new <CODE>ReverifyBuilderInEnclosingCnstrXmpl</CODE> with defaults.</P>
**/
public ReverifyBuilderInEnclosingCnstrXmpl() {
//Does not reverify. No need.
this(new ReverifyBuilderInEnclosingCnstrXmpl.Cfg());
}
private ReverifyBuilderInEnclosingCnstrXmpl(ReverifyBuilderInEnclosingCnstrXmpl.Cfg rbdx_c) {
sName = rbdx_c.sName;
iAge = rbdx_c.iAge;
ReverifyBuilderInEnclosingCnstrXmpl.Cfg.zcibValues(rbdx_c, sName, iAge, "constructor");
}
public static class Cfg {
private String sName = null;
private int iAge = -1;
private boolean bReVrfy = false;
public Cfg() {
//Defaults
bReVrfy = false;
name("Broom Hilda");
age(127);
}
//Self-returning configuration...START
//No way to unset.
public Cfg reverifyInEnclosing() {
bReVrfy = true;
return this;
}
public Cfg name(String s_name) {
zcib_name(s_name, "name");
sName = s_name;
return this;
}
public Cfg age(int i_age) {
zcib_age(i_age, "age");
iAge = i_age;
return this;
}
//Self-returning configuration...END
//Validate config...START
public static final void zcibValues(ReverifyBuilderInEnclosingCnstrXmpl.Cfg rbdx_c, String s_name, int i_age, String s_clgFunc) {
try {
if(!rbdx_c.bReVrfy) {
return;
}
} catch(NullPointerException npx) {
throw new NullPointerException("zcibValues: rbdx_c");
}
zcib_name(s_name, s_clgFunc);
zcib_age(i_age, s_clgFunc);
}
public static final void zcib_name(String s_name, String s_clgFunc) {
if(s_name == null || s_name.length() == 0) {
throw new IllegalArgumentException(s_clgFunc + ": s_name (" + s_name + ") is null or empty.");
}
}
public static final void zcib_age(int i_age, String s_clgFunc) {
if(i_age < 0) {
throw new IllegalArgumentException(s_clgFunc + ": i_age (" + i_age + ") is negative.");
}
}
//Validate config...END
public ReverifyBuilderInEnclosingCnstrXmpl build() {
return (new ReverifyBuilderInEnclosingCnstrXmpl(this));
}
}
}

最佳答案

首先 - 构建器模式不是本质上是线程不安全的。我不确定你是如何得出结论的。每个打算使用构建器的线程都将创建自己的 Builder 对象,以 Joshua Bloch 实用而优美的方式填充它并使用它来构造对象。在该机制中的任何地方都没有受到影响的 static 变量,除非您自己引入它,否则没有线程不安全。

在我看来,您对验证的担忧是一种粗略的预优化,它会产生极其人为设计和极其臃肿的代码。 没有理由仅仅因为您知道数据有效就试图避免验证。验证几乎总是微不足道的,通常只需要几条指令。通过使用这些可怕的静态验证方法使类膨胀,您可能会增加数千倍的 cpu 周期,仅仅是为了加载这个膨胀的代码,而不是通过避免验证所节省的时间。

将你做作的和臃肿的代码与这个清晰、简洁和明显正确的和线程安全代码进行比较,看看我的意思:

public class Thing {

public final String name;
public final int age;

public Thing() {
this(new Thing.Builder());
}

private Thing(Thing.Builder builder) {
name = builder.name;
age = builder.age;
}

public static class Builder {

private String name = null;
private int age = -1;

public Builder() {
name("Broom Hilda");
age(127);
}

public Builder name(String name) {
if (name == null || name.length() == 0) {
throw new IllegalArgumentException("Thing.Builder.name (" + name + ") is null or empty.");
}
this.name = name;
return this;
}

public Builder age(int age) {
if (age < 0) {
throw new IllegalArgumentException("Thing.Builder.age (" + age + ") is negative.");
}
this.age = age;
return this;
}

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

关于java - 使 Bloch 的构建器模式线程安全 : Rechecking necessary in enclosing constructor if NEVER invalid?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20937880/

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