Java Builder Utility Class?

469 Views Asked by At

I've been Googling around for a while trying find the answer to this question without any success.

The way I understand how to create a class using the Builder style is like this:

public class MyClass {

    private String myString;
    private int myInt;

      public static class Builder {

        private String myString;
        private int myInt;
  
        public Builder() {}
    
        public Builder setString(String myString) {
          this.myString = myString;
          return this;
        }

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

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

    private MyClass(Builder build) {
      this.myString = build.myString;
      this.myInt = build.myInt;
    }
}

Which is great! It is a powerful style for class design. However, what I would like to do, is have a utility class where everything is static and public but also have a builder to set up the class. But the only way I seem to be able to do that, is by creating a new instance of a builder class which forces the user to call new on the parent class ... but the parent class isn't supposed to be instantiated, so it seems a bit confusing to have a Builder that has to be instantiated for a class that doesn't... The only way I've been able to offer any kind of a builder for a public utility class is by returning void on the final build statement, where all of the build options affect change on the parent class...

So my question is, is there a way to offer "Builder style" functionality on a public static utility class such that there would be no need to instantiate any class at all in the use of that functionality?

Edit:

I guess I should clarify, that what I am trying to offer to an end user of the class, is the ability to invoke a Builder style interface WITHOUT instantiating ANY classes at all... like this:

MyClass.Builder.option1().option2().build();

Notice I did NOT do this:

MyClass myClass = new MyClass.Builder()...

Because that is exactly what I DONT want to do...

Edit2:

Take the following class for example:

import java.util.*;

class MyClass {

    private static List<String>            userList       = new ArrayList<>();
    private static Map<Integer, String>    userMap        = new HashMap<>();
    private static LinkedList<Double>      userDoubleList = new LinkedList<>();
    private static Map<Integer, SomeClass> someClassMap   = new HashMap<>();

    public static void method1(String userString) {
        userList.add(userString);
    }

    public static void method2(Integer userNumber, String userString) {
        userMap.put(userNumber, userString);
    }

    public static void method3(Double userDouble) {
        userDoubleList.addLast(userDouble);
    }

    public static void method4(Integer userInteger, SomeClass userClass) {
        someClassMap.put(userInteger, userClass);
    }
}

I would like for the user to be able to set up the class using a Builder style like this:

MyClass.Builder.option1("My String").option3(25.4).build();

Or however that would end up actually looking ... I want to be able to have them set up the parameters of the class without needing to create a whole bunch of different public static methods that provide the variety of options that are inherent in the class...

I hope that makes sense ...

1

There are 1 best solutions below

1
On

You can use Lombok to produce easily Builders

Use the annotation @Builder on your class

@Builder
public class MyClass {
    private String myString;
    private int myInt;
}

Then you can use it like the following code :

public void foo(){
   MyClass myClass = MyClass.builder().myInt(0).myString("bar").build();
}

Take a look here for lombok

Add the following dependency to manage it

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <scope>provided</scope>
    <version>1.18.20</version>
</dependency>