Java

[모던 자바 인 액션] 동작 파라미터화

Tommy__Kim 2023. 5. 10. 12:23

실생활에서는 소비자들의 요구는 시도때도 없이 바뀝니다. 

사과를 분류하는 메서드가 있다고 가정하겠습니다.

소비자들의 요구사항은 시도 때도 없이 많을 것입니다. 

  • 녹색 사과만 보여줘!
  • 녹색 사과인데 100g 이 넘는 사과만 보여줘!
  • 빨간 사과를 보여줘!
  • 빨간 사과인데 100g 안되는 사과만 보여줘

이 외에도 소비자들이 원하는 조건에 따라 계속 바뀔 것입니다. 

이러한 조건을 효과적으로 대응할 수 있는 방법이 바로 동작 파라미터화입니다.

 

동작 파라미터화

해당 예제에서는 Predicate를 사용했는데, Predicate는 참 혹은 거짓을 반환하는 함수입니다.

 

 

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


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

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

public class AppleRedAndHeavyPredicate implements ApplePredicate {

    @Override
    public boolean test(Apple apple) {
        return RED.equals(apple.getColor())
                && apple.getWeight() > 150;
    }
}

ApplePredicate라는 인터페이스를 만들고 각각의 목적에 맞게 인터페이스를 구현한 클래스들을 만들면 메서드에서 보다 간편하게 파라미터들을 넘겨줄 수 있습니다. 

밑의 예시에서 System.out.println을 보면 filterApples 메서드에 인자로 ApplePredicate 구현체를 넘기는 것을 확인할 수 있습니다. 

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

이러한 방식은 메서드가 내부에서 컬렉션을 반복하는 로직과 컬렉션의 각 요소에 적용할 동작을 분리 할 수 있다는 큰 이득을 취할 수 있습니다.

 

익명 클래스 

익명클래스는 자바의 local class와 비슷한 개념입니다. 

익명 클래스를 이용하면 클래스 선언과 인스턴스화를 동시에 할 수 있다는 특징을 지닙니다. 

사용 방법은 다음과 같습니다. 

System.out.println(
        filterApples(inventory, new ApplePredicate() {
            @Override
            public boolean test(Apple apple) {
                return RED.equals(apple.getColor());
            }
        })
);

익명클래스는 ApplePredicate를 클래스를 만들지 않고 바로 사용할 수 있다는 장점을 지닙니다. 

하지만 코드에 많은 부분이 반복되어 다소 지저분한 코드가 되기 쉽습니다. 

 

람다 표현식

람다를 사용하면 보다 간단하게 구현이 가능합니다. 

System.out.println(filterApples(inventory, (Apple apple) -> RED.equals(apple.getColor())));

 

 

'Java' 카테고리의 다른 글

[Java] Exception의 종류 및 처리 방법  (0) 2023.06.12
[Java] Object란 무엇인가요?  (0) 2023.06.02
오버로딩과 오버라이딩에 대해  (0) 2023.05.01
Java Parameter Passing Mechanism  (0) 2023.04.26
Java Collection Framework  (0) 2023.04.25