How many constructor arguments is too many?

前端 未结 15 1262
[愿得一人]
[愿得一人] 2020-11-29 15:03

Let\'s say you have a class called Customer, which contains the following fields:

  • UserName
  • Email
  • First Name
  • Last Name

15条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-29 15:45

    In your case, stick with the constructor. The information belongs in Customer and 4 fields are fine.

    In the case you have many required and optional fields the constructor is not the best solution. As @boojiboy said, it's hard to read and it's also hard to write client code.

    @contagious suggested using the default pattern and setters for optional attributs. That mandates that the fields are mutable, but that's a minor problem.

    Joshua Block on Effective Java 2 say that in this case you should consider a builder. An example taken from the book:

     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  
         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;  
         soduim            = builder.sodium;  
         carbohydrate      = builder.carbohydrate;  
       }  
    }  
    

    And then use it like this:

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

    The example above was taken from Effective Java 2

    And that doesn't only applies to constructor. Citing Kent Beck in Implementation Patterns:

    setOuterBounds(x, y, width, height);
    setInnerBounds(x + 2, y + 2, width - 4, height - 4);
    

    Making the rectangle explicit as an object explains the code better:

    setOuterBounds(bounds);
    setInnerBounds(bounds.expand(-2));
    

提交回复
热议问题