전체 페이지뷰

2013년 8월 29일 목요일

Item 2: Consider a builder when faced with many constructor parameters

the telescoping constructor pattern works, but it is hard to write
client code when there are many parameters, and harder still to read it

JavaBeans pattern has serious disadvantages of its own.
Because construction is split across multiple calls, a JavaBean may be in an
inconsistent state partway through its construction.

A related disadvantage is that the JavaBeans pattern precludes
the possibility of making a class immutable (Item 15), and requires
added effort on the part of the programmer to ensure thread safety.

there is a third alternative that combines the safety of the telescoping
constructor pattern with the readability of the JavaBeans pattern. It is a form of the
Builder pattern

// Builder Pattern
public class NutritionFacts {
    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;
   
    public static class Builder {
        // Required parameters
        private final int servingSize;
        private final int servings;
       // Optional parameters - initialized to default values
        private int calories = 0;
        private int fat = 0;
        private int carbohydrate = 0;
        private int sodium = 0;
       
        public Builder(int servingSize, int servings) {
            this.servingSize = servingSize;
            this.servings = servings;
        }

        public Builder calories(int val)
        { calories = val; return this; }
        public Builder fat(int val)
        { fat = val; return this; }
        public Builder carbohydrate(int val)
        { carbohydrate = val; return this; }
        public Builder sodium(int val)
        { sodium = val; return this; }

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

   private NutritionFacts(Builder builder) {
       servingSize = builder.servingSize;
       servings = builder.servings;
       calories = builder.calories;
       fat = builder.fat;
       sodium = builder.sodium;
       carbohydrate = builder.carbohydrate;
  }
}

NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8).
calories(100).sodium(35).carbohydrate(27).build();

This client code is easy to write and, more importantly, to read. The Builder pattern
simulates named optional parameters as found in Ada and Python.

Class.newInstance breaks compile-time exception checking

Also, the Builder pattern is more verbose than the telescoping
constructor pattern, so it should be used only if there are enough parameters, say,
four or more. But keep in mind that you may want to add parameters in the future

In summary, the Builder pattern is a good choice when designing classes
whose constructors or static factories would have more than a handful of
parameters,


reference design pattern
Builder pattern

댓글 없음:

댓글 쓰기