동적 파라미터화는 무엇인가

Shinny·2022년 5월 26일
0

JAVA 공부

목록 보기
1/1
post-custom-banner

Modern Java in Action(책)을 공부하면서 정리하는 글입니다.

시시각각 변하는 사용자의 요구에도 엔지니어링적인 비용을 최소화할 수 있다면, 정말 좋을 것이다. 이렇게 되기 위해서는 첫번째, 기능의 구현 자체가 간결해야 하며, 두번째, 유지보수가 쉬워야 한다.

그래서 동적 파라미터화가 등장했다.

동적 파라미터화, 너는 누구야?

동적 파라미터화는 아직 어떻게 실행할지 결정하지 않은 코드 블록을 의미한다. 코드 블록의 실행은 나중에 이루어지겠지만, 코드 블록 자체는 미리 만들어놓을 수 있다. 그리고 이 코드 블록은 메소드의 인수로 쓰일 수 있다.

원래는 동적 파라미터화를 추가하기 위해서 써야하는 코드가 많았다. 하지만 자바 8에서는 람다를 통해 이를 훨씬 간결하게 해결했다.

지금부터 메서드의 동작을 파라미터화한 과정을 코드로 정리해보겠다.

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

ApplePredicate 라는 이름의 인터페이스를 만들어서 test 라는 이름의 메소드를 정의했으니 해당 인터페이스를 상속한 클래스를 자유자재로 만들어서 test 메소드를 오버라이딩할 수 있다. 그리고 filterApples의 메소드에 그를 동작 파라미터화 해서 인자로 줄 수 있다.

public class AppleLightWeightRedColor implements ApplePredicate {
    public boolean test(Apple apple) {
        return RED.equals(apple.getColor()) 
                && apple.getWeight() < 150;
    }
}

예를 들어 이렇게 만들어서 위에서 만든 사과 필터 메소드의 인자로 전달해줄 수가 있게 되는 것이다. filterApples 메서드 내부에서 컬렉션을 반복하는 로직과 컬렉션의 각 요소에 적용할 동작을 분리할 수 있다는 점에서 소프트웨어 엔지니어링적인 이점을 지닌다. 그리고 이것은 동작 파라미터화의 가장 큰 장점이다.

인터페이스 생성 → 클래스 생성 → 오버라이딩… 과정을 좀 더 간소화할 수는 없을까?

그래서 자바는 클래스 선언과 인스턴스화를 동시에 수행할 수 있도록 익명 클래스 기법을 제공한다. 익명 클래스를 사용하면 위에서 적은 코드를 이렇게 단순화할 수 있다.

List<Apple> redApples = filterApples(inventory, new ApplePredicate() {
            public boolean test(Apple apple) {
                return RED.equals(apple.getColor());
        }
});

새롭게 인터페이스를 상속받은 클래스를 만들 필요가 없어서 코드의 줄은 조금 줄었으나 여전히 보기가 불편한 점이 있다. 하지만 동작 파라미터화의 경우 분명한 장점이 있다. 그래서 자바 8은 람다식을 통해 동작 파라미터화의 사용을 좀 더 편리하고, 간결하고 또 직관적으로 만들어주었다.

람다식, 한번 써보자!

List<Apple> redApples = filterApples(inventory,
        (Apple apple) -> RED.equals(apple.getColor()));

아래는 Comparator를 구현해서 메서드의 동작을 다양화한 예시이다.

public interface Comparator<T> {
		int compare(T o1, T o2);
}

inventory.sort(new Comparator<Apple>() {
    public int compare(Apple a1, Apple a2) {
        return a1.getWeight().compareTo(a2.getWeight());
        }
        });

// 람다식으로 간단하게 표현하기
inventory.sort(
(Apple a1, Apple a2) -> a2.getWeight().compareTo(a2.getWeight()));

정리해보자.

  • 동작 파리미터화를 쓰면, 메서드의 인수로 코드를 전달함으로써 내부적으로 더 다양한 동작을 가능하게 한다.
  • 동작 파라미터화를 사용하게 되면, 요구사항에 더 잘 대응하는 유연한 코드를 짤 수가 있다.
  • 동작을 메소드의 인수로 전달하는 코드 전달 기법에는 익명 클래스, 람다식 등이 있다.
profile
비즈니스 성장을 함께 고민하는 개발자가 되고 싶습니다.
post-custom-banner

0개의 댓글