Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Joshua Bloch's Builder pattern and PMD warnings

I have written a class using Joshua Bloch's Builder pattern, which is similar to this Pizza example:

public class Pizza {
  private int size;
  private boolean cheese;
  private boolean pepperoni;
  private boolean bacon;

  public static class Builder {
    //required
    private final int size;

    //optional
    private boolean cheese = false;
    private boolean pepperoni = false;
    private boolean bacon = false;

    public Builder(int size) {
      this.size = size;
    }

    public Builder cheese(boolean value) {
      cheese = value;
      return this;
    }

    public Builder pepperoni(boolean value) {
      pepperoni = value;
      return this;
    }

    public Builder bacon(boolean value) {
      bacon = value;
      return this;
    }

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

  private Pizza(Builder builder) {
    size = builder.size;
    cheese = builder.cheese;
    pepperoni = builder.pepperoni;
    bacon = builder.bacon;
  }
}

but PMD reported 2 warnings:

  1. (Pointing to method Builder.build()) Avoid instantiation through private constructors from outside of the constructor's class. Instantiation by way of private constructors from outside of the constructor's class often causes the generation of an accessor. A factory method, or non-privitization of the constructor can eliminate this situation. The generated class file is actually an interface. It gives the accessing class the ability to invoke a new hidden package scope constructor that takes the interface as a supplementary parameter. This turns a private constructor effectively into one with package scope, and is challenging to discern.
  2. Class cannot be instantiated and does not provide any static methods or fields. A class that has private constructors and does not have any static methods or fields cannot be used.

Should I just ignore these warnings?

Another question: the private fields in class Pizza and Builder are duplicate. This will be annoying when the number of private fields getting bigger. Is there any way to avoid it?

like image 908
chance Avatar asked Oct 25 '22 10:10

chance


1 Answers

About how to remove duplication.

I'll get more downvotes :) But maybe something like this?

class Pizza {
private int size;
private boolean cheese;
private boolean pepperoni;
private boolean bacon;

public static class Builder {
    private Pizza pizza = new Pizza();

    public Builder(int size) {
        pizza.size = size;
    }

    public Builder cheese(boolean value) {
        pizza.cheese = value;
        return this;
    }

    public Builder pepperoni(boolean value) {
        pizza.pepperoni = value;
        return this;
    }

    public Builder bacon(boolean value) {
        pizza.bacon = value;
        return this;
    }

    public Pizza build() {
        return pizza;
    }
}

private Pizza() {
}
}
like image 140
weekens Avatar answered Oct 27 '22 11:10

weekens