JAVA/MODERN JAVA

코드의 점진적인 발진으로 동적파라미터를 이해해보자

gracelove91 2020. 3. 20. 18:22

아래 내용은 책 모던 자바 인 액션(http://www.yes24.com/Product/Goods/77125987?scode=032&OzSrank=2) 을 정리한것임을 밝힙니다.

코드의 점진적인 발진으로 동적파라미터를 이해해보자

첫번째 요구사항.

사과를 재배하는 농부 후안의 요구사항

  • "제가 수확한 사과 중에 색깔이 "GREEN"인 사과만 수집해주세요
  • FirstStep.class
      public static List<Apple> filterGreenApples(List<Apple> inventory) {
          List<Apple> result = new ArrayList<>();
          for (Apple apple : inventory) {
              if (GREEN.equals(apple.getColor())) {
                  result.add(apple);
              }
          }
          return result;
      }

두번째 요구사항

후안이 또다른 요구를 해왔다.

  • "제가 수확한 사과 중에 무게가 xxx 이상인 것들만 수집해주세요"
  • SecondStep.class
       public static List<Apple> filterApplesByWeight(List<Apple> inventory, int weight) {
           List<Apple> result = new ArrayList<>();
           for (Apple apple : inventory) {
               if (apple.getWeight() > weight) {
                   result.add(apple);
               }
           }
           return result;
       }

세번째 요구사항

  • "수확한 사과 중에 색깔이 xxx고, 무게가 yyy 이상인 사과만 수집해주세요"
  • ThirdStep.class
      public static List<Apple> filterApples(List<Apple> inventory, Color color, int weight, boolean flag) {
          List<Apple> result = new ArrayList<>();
          for (Apple apple : inventory) {
              if ((flag && apple.getColor().equals(color)) || (!flag && apple.getWeight() > weight)) {
                  result.add(apple);
              }
          }
          return result;
      }

각 요구사항마다 중복 코드가 너무 많다. 해결책?

  • 변화하는 요구사항에 좀 더 유연하게 대응할 수 있는 방법이 있다. Apple의 속성에 기초해 boolean 값을 반환하는 방법이 있다.

    • Predicate 인터페이스를 정의하자.
    • 그 다음 Predicate의 구현체인 AppleGreenColorPredicate, AppleHeavyWeightPredicate 을 만들자.
    • 클라이언트 코드(Main.class)에서 인자값으로 구현체를 사용하면 된다.
      • 전략패턴 찾아볼 것
  • ApplePredicate.class

      public interface ApplePredicate {
        boolean test(Apple apple);
      }
  • AppleGreenColorPredicate.class

      public class AppleGreenColorPredicate implements ApplePredicate{
        @Override
        public boolean test(Apple apple) {
            return GREEN.equals(apple.getColor());
        }
      }
  • AppleHeavyWeightPredicate.class

      public class AppleHeavyWeightPredicate implements ApplePredicate {
        @Override
        public boolean test(Apple apple) {
            return apple.getWeight() > 150;
        }
      }
  • FourthStep.class

      public class FourthStep {
        public static List<Apple> filterApples(List<Apple> apples, ApplePredicate predicate) {
            List<Apple> result = new ArrayList<>();
            for (Apple apple : apples) {
                if (predicate.test(apple)) {
                    result.add(apple);
                }
            }
            return result;
        }
      }
  • Main.class

      public class Main {
        public static void main(String[] args) {
            List<Apple> inventory = Arrays.asList(
                    new Apple(80, Color.GREEN),
                    new Apple(155, Color.GREEN),
                    new Apple(120, Color.RED)
            );
    
            List<Apple> heavyApples = FourthStep.filterApples(inventory, new AppleHeavyWeightPredicate());
            heavyApples.forEach(System.out::println);
    
            List<Apple> greenApples = FourthStep.filterApples(inventory, new AppleGreenColorPredicate());
            greenApples.forEach(System.out::println);
        }
      }