Java 单身汉与建筑商(约书亚之路)

Java 单身汉与建筑商(约书亚之路),java,builder,Java,Builder,我正在根据Joshua的构建器模式构建一个构建器。我的问题是我怎样才能做到单身? 为了详细说明我的观点,如果我有下面的生成器 public class Widget { public static class Builder { private String name; public Builder( String name) { this.name = name; } public Widget

我正在根据Joshua的构建器模式构建一个构建器。我的问题是我怎样才能做到单身? 为了详细说明我的观点,如果我有下面的生成器

public class Widget {
    public static class Builder {
        private String name;

        public Builder( String name) {
            this.name = name;
        }

        public Widget build() {
            Widget result = new Widget(this);
            return result;
        }
        public Builder model( String value ) {
            this.model = value;
            return this;
        }
    }

    private final String name;

    private Widget( Builder b ) {
        this.name = b.name;
    }

    // ... etc. ...
}
我会从另一个类中调用此生成器,例如 新建Widget.Builder().name(“abc”).build()


但是,如果我只想要这个小部件的一个实例,或者我需要从多个地方访问这个小部件,而不需要每次都创建一个新的小部件,该怎么办呢。理想情况下,我希望将实例化限制在Widget类中。有什么想法吗

IMHO、Singleton和Builder模式似乎不在一起:如果只有一个实例要构建,为什么需要一个Builder

如果您需要重用构建器对象,因为您希望多次构建类似的对象,那么只需保留对该构建器的引用,并根据需要多次使用它(因为您将其设置为静态):

然后,您可以创建几个小部件:

Widget w1 = builder.build();
Widget w2 = builder.build();
...

如果只有一个构建器对象,则可以使用如下单例模式:

public class Widget {
public static class Builder {
    private static Builder builder;
    private String name;

    public Builder getInstance(String name){
       if (instance==null){
         instance=new Builder(name);
       }
       return instance;
    }

    private Builder( String name) {
        this.name = name;
    }

    public Widget build() {
        Widget result = new Widget(this);
        return result;
    }
    public Builder model( String value ) {
        this.model = value;
        return this;
    }
}

private final String name;

private Widget( Builder b ) {
    this.name = b.name;
}

// ... etc. ...
}

如果您有多个构建器,那么在这个类中您可能需要一个静态映射

如果您真的需要一个单例,Joshua也有一些建议。

如果您需要这样做,并且希望避免污染您的构建器模式,那么添加一个单例来保存构建器的集中实例

public enum CentralWidgitBuilder{
  INSTANCE; //Effective Java singleton technique

  private final Widget.Builder mBuilder = new Widget.Builder();

  public Widget.Builder getBuilder(){
    return mBuilder;
  }
}
然后从任何地方引用:

CentralWidgitBuilder.INSTANCE.getBuilder().

我选择builder的原因是因为这个对象有20个字段要设置,而不是在构造函数中传递它们,我更喜欢builder方式,而我需要singleton的原因是因为这些字段是配置数据,不会经常更改。@Java If和我的意思是,那么这就不适用了。@Java您已经编辑了您的问题,以澄清您想要一个小部件单例。这似乎证实了这可能不是前进的最佳途径。你可能想读书,是的,有道理。非常感谢,但是如果我想让Widget成为singleton呢?然后将静态实例放在Widget类中,并将a构建器传递给getinstance方法
CentralWidgitBuilder.INSTANCE.getBuilder().