시작하기 앞서

이번 방학에 자바 공부의 필요성을 느끼고 유명한 서적들을 참고하여 자바를 공부하려고 마음을 먹었다. 토비의 스프링, 이펙티브 자바, 리팩토링 등등 너무 많은 책을 추천 받았지만 그 중에서 첫번째로 읽을 책은 <모던 자바 인 액션>으로 정했다. 아직 첫번째 주제에 대해서 읽고 있는데도 좋은 책이라는 것이 느껴진다. 어찌됐든 배운것을 토대로 우테코 프리코스 코드를 리팩토링 하며 진행해볼 생각이다. 화이팅!

동작 파라미터화란?

말 그대로 동작을 파라미터(메소드의 매개변수)로 넘겨주는 것이다. 이 기법을 통해서 얻는 이점은 반복을 제거할 수 있는 것이다.
먼저 이 책에 소개되는 반복 코드를 살펴보고 내가 우테코 프리코스에 응시할 때 작성했던 반복코드를 살펴볼 것이다. 그리고 가차없이 제거할 것이다. 다시 한번 화이팅!

책에서 소개된 반복 코드

프로그램의 기능은 이렇다. 고객이 처음엔 사과의 무게를 필터링하는 프로그램을 요청했다. 그리고 하루 후에 사과의 색깔을 필터링하는 프로그램을 요청했다. 그리고 또 하루 후에 사과의 무게와 색깔 모두 필터링하는 프로그램을 요청했다.

사과의 색깔을 필터링하는 프로그램

public static List filterApplesByColor(List inventory, Color color) { 
  List result = new ArrayList<>();
  for (Apple apple: inventory) {
    if (apple.getColor().equals(color)) {
      result.add(apple);
    }
  }
  return result;
}

사과의 무게를 필터링하는 프로그램

public static List filterApplesByWeight(List inventory, int weight) { 
  List result = new ArrayList<>();
  for (Apple apple: inventory) {
    if (apple.getWeight() > weight) {
      result.add(apple);
    }
  }
  return result;
}

무게와 색깔을 모두 필터링 하는 프로그램

public static List filterApples(List inventory, Color,
                                       int weight, boolean flag) { 
  List result = new ArrayList<>();
  for (Apple apple: inventory) {
    if ((flag && apple.getColor().equals(color)) ||
        (!flag  && apple.getWeight() > weight)) { 
        result.add(apple);
    }

  }
  return result;
}

위의 세 프로그램은 조건문과 매개변수 빼고는 모두 반복되는 코드를 가지고 있다. 뿐만아니라 이 코드들을 사용하면 아래와 같은 코드가 생긴다.

List greenApples = filterApples(inventory, GREEN, 0, true);
List heavyApples = filterApples(inventory, null, 150, false);

위의 코드는 각 매개변수들이 무엇을 의미하는지 명확하지 않으며 유지보수하기도 어려운 코드가 된다. 동작 파라미터화 코드를 작성함으로써 이런 문제들과 반복을 제거할 수 있다.

동작파라미터화 코드 작성하기

핵심적은 방법은 선택 조건을 결정하는 인터페이스를 정의하자이다. 다시말해서 (코드로 살펴보겠지만) 인터페이스를 구현해서 사과가 녹색인가? 150그램 이상인가? 처럼 질의를 통해 참 또는 거짓을 반환하는 Predicate 메소드를 만드는 것이다. 이는 우테코에서 받은 피드백인 메소드에 메세지를 보내라와 일치한다. 더욱 이 책을 읽고 싶어지는 대목이었다.

선택 조건 결정 인터페이스

public interface ApplePredicate {
    boolean test(Apple apple);
}

Predicate Method를 구현하는 Class

public class AppleHeavyWeightPredicate implements ApplePredicate {
    public boolean test(Apple apple) {
        return apple.getWeight() > 150;
    }
}
public class AppleGreenColorPredicate implements ApplePredicate {
    public boolean test(Apple apple) {
        return GREEN.equals(apple.getColor());
    }
}

위의 인터페이스를 두 가지 동작으로 implements했다.

동작 파라미터화 코드 사용하기

public static List filterApples(List inventory,
                                                    ApplePredicate p) {
    List result = new ArrayList<>();
    for (Apple apple: inventory) {
        if (p.test(apple)) {
            result.add(apple);
        }
    }
    return result;
}

위의 메소드는 아래와 같이 사용할 수 있다.

filterApples(inventory, new AppleHeavyWeightPredicate());
filterApples(inventory, new AppleGreenColorPredicate());

이렇게 선택 결정 인터페이스를 구현한 클래스를 매개변수로 넘겨줌으로써 다양한 동작을 할 수 있다. 클래스의 이름을 잘만 지으면 의도를 알기 쉽고 유지보수도 쉬운 코드를 작성할 수 있다. 이 책을 읽으면서 우테코에 제출 했던 코드들 상당수에 동작 파라미터화 코드를 적용할 부분이 많을 것 같다는 생각이 들었다. 그러니까 직접 리팩토링 해보자.

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 라이프코리아트위터 공유하기
  • shared
  • 카카오스토리 공유하기