ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 이펙티브 자바 - ITEM2
    ⏰ 오늘의 공부/Java 2022. 1. 5. 01:51

    많은 Parameter가 있는 Constructor 는 Builder를 고려하라

    ex) 클래스에서 여러 파라미터 중 반드시 필요한 파라미터가 있고 없어도 되는 파라미터가 있다.

    public class NutritionFacts {
        private final int servingSize; // 1회 제공량 (need)
        private final int servings; // 총 n회 제공량 (need)
        private final int calories; // 1회 제공량당 (need)
        private final int fat; // g/1회 제공량 (option)
        private final solium; // mg/1회 제공량 (option)
        private final carbohydrate; // g/1회 제공량 (option)
    }


    적절하게 대응하기 위한 방안


    1. 여러 개의 Constructor를 둔다.
      public NutritionFacts(int servingSize, int servings, int calories) {
      	this.servingSie = servingSize;
      	this.servings = servings;
      	this.calories = calories;
      }
      
      public NutritionFacts(int servingSize, int servings, int calories, int fat) {
      	this.servingSie = servingSize;
      	this.servings = servings;
      	this.calories = calories;
      	this.fat = fat;
      }
      
      public NutritionFacts(int servingSize, int servings, int calories, int solium) {
      	this.servingSie = servingSize;
      	this.servings = servings;
      	this.calories = calories;
      	this.solium = solium;
      }
      
      // ...
      • 타입과 인자의 순서를 바꾸는 실수를 하게 되면 오류를 찾기 매우 어려울 수 있다.
      • 가독성 좋지 않다.

    2. Java Beans Pattern 사용
      • 매개변수가 없는 생성자로 객체를 생성한 후에 수정자(setter) 메서드를 호출해서 값을 채우는 것
        public NutritionFacts() {}
        
        public void setServingSize(int servingSize) {
        	this.servingSize = servingSize;
        }
        
        public void setServing(int servings) {
        	this.servings = servings;
        }
        
        public void setCalories(int calories) {
        	this.calories = calories;
        }
        
        // ...
        
        // 실제 객체 생성할 때
        public void someMethod() {
        	NutritionFacts nutritionFacts = new NutritionFacts();
        	nutritionFacts.setServingSize(3);
        	nutritionFacts.setServing(1);
        	nutritionFacts.setCalories(100);
        	...
        }
        • 1회의 메서드 호출로 객체 생성을 완료할 수 없게 된다.
        • 객체의 일관성(consistency)이 무너짐 / 변경 불가능(immutable)한 클래스를 만들 수 없게 된다.

         

    3. 빌더 패턴 사용
      • 필요한 객체를 직접 만드는 것이 아니라 필수 매개변수만으로 생성자를 호출하여 빌더 객체를 얻고 수정자(setter) 역할을 하는 메서드들을 연쇄적으로 호출하여 원하는 매개변수를 설정
      • 마지막으로 build 메서드를 호출하여 immutable한 객체를 얻는다.
        public class NutritionFacts {
            private final int servingSize; // 1회 제공량 (need)
            private final int servings; // 총 n회 제공량 (need)
            private final int calories; // 1회 제공량당 (need)
            private final int fat; // g/1회 제공량 (option)
        
            public static class Builder {
                private final int servingSize;
                private final int servings;
                private final int calories;
                private int fat;
        
                public Builder(int servingSize, int servings, int calories) {
                    this.servingSize = servingSize;
                    this.servings = servings;
                    this.calories = calories;
                }
        
                public Builder fat(int val) {
                    this.fat = val;
                    return this;
                }
        
                public NutritionFacts build() {
                	return new NutritionFacts(this);
                }
            }
        
            private NutritionFacts(Builder builder) {
                this.servingSize = builder.servingSize;
                this.servings = builder.servings;
                this.calories = builder.calories;
                this.fat = builder.fat;
            }
        }
        
        // 사용방법
        NutritionFacts builder = new NutritionFacts.Builder(240, 9, 100).setFat(3).build();
         점층적인 생성자 패턴의 안정성과 자바빈 패턴의 가독성을 함께 가질 수 있다.

      • 단점
        • Builder를 항상 만들어야 하기 때문에 생성 비용이 무조건 생긴다.
        • 점층적 생성자 패턴보다 장황하여 적은 갯수의 파라미터일 경우 오히려 좋지 않을 수 있다.

    '⏰ 오늘의 공부 > Java' 카테고리의 다른 글

    이펙티브 자바 - ITEM1  (0) 2022.01.05

    댓글

Designed by Tistory.