4

I am building a builder based on Joshua's builder pattern. my question is how can I make it singleton? to elaborate my point, if I have the below builder

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. ...
}

I would call this builder from another class like new Widget.Builder().name("abc").build()........

but what if I want only one instance of this Widget or I have a need to access this Widget from multiple places without resorting to creating a new one every time. Ideally I would like to confine the instantiation with in the Widget class. Any thoughts?

Java
  • 161
  • 1
  • 3
  • 11

4 Answers4

7

IMHO, Singleton and Builder Patterns don't seem to go together: why would you need a builder if there is only one instance to build?

If what you need is to reuse a Builder object because you want to build a similar object several times, you can simply keep a reference to that Builder and use it as many times as you want (since you made it static):

Widget.Builder builder = new Widget.Builder("abc").model("def");

Then you can create several Widgets:

Widget w1 = builder.build();
Widget w2 = builder.build();
...
assylias
  • 297,541
  • 71
  • 621
  • 741
  • 1
    The reason I opted for builder was because this object has like 20 fields to set and instead of passing them all in constructor I prefer the builder way and the reason I need singleton is because these fields are config data that doesn't change very often. – Java Aug 01 '12 at 21:43
  • 1
    @Java If [you really need a singleton](http://stackoverflow.com/questions/228164/on-design-patterns-when-to-use-the-singleton) and I mean [that you really need one](http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons?lq=1), then this would not apply. – assylias Aug 01 '12 at 21:49
  • @Java you have edited your question to clarify that you want a Widget singleton. That seems to confirm that it may not be the best way going forward. You might want to read [this post about configurable singletons](http://stackoverflow.com/questions/1050991/singleton-with-arguments-in-java). – assylias Aug 01 '12 at 22:28
1

If you really need a Singleton, Joshua also has advice on the best way to make a singleton in modern Java.

Don Roby
  • 39,169
  • 6
  • 84
  • 105
1

If you need to do this, and want to avoid polluting your builder pattern then add a singleton to hold a centralized instance of the builder.

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

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

  public Widget.Builder getBuilder(){
    return mBuilder;
  }
}

Then to reference from anywhere:

CentralWidgitBuilder.INSTANCE.getBuilder().
weston
  • 51,132
  • 20
  • 132
  • 192
0

If there is only one builder object so you can use singleton pattern like this:

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. ...
}

If you have multiple builders you may need a static Map in this class

Masood_mj
  • 1,036
  • 8
  • 21