본문 바로가기
Book

[독서 기록] 모던 자바 인 액션 2장 - 동작 파라미터화 코드 전달하기

by Renechoi 2023. 1. 4.

 

 

 

다음은 만류에도 불구하고 모든 속성을 메서드 파라미터로 추가한 모습이다. 

 

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) || ...

 

형편없는 코드다. 대체 true와 false는 뭘 의미하는 걸까? 

- 71p

 

 

 

참 또는 거짓을 반환하는 함수를 프레디케이트라고 한다. 선택 조건을 결정하는 인터페이스를 정의하

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

 

다음 예제처럼 다양한 선택 조건을 대표하는 여러 버전의 ApplePredicate를 정의할 수 있다. 

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

- 72p 

 

 

 

ApplePredicate 는 어떻게 다양한 동작을 수행할 수 있을까? filterApples 에서 ApplePredicate 객체를 받아 애플의 조건을 검사하도록 메서드를 고쳐야한다. 이렇게 동작 파라미터화, 즉 메서드가 다양한 동작 (또는 전략)을 받아서 내부적으로 다양한 동작을 수행할 수 있다.

- 73p 

 

 

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;
}

= 프레디케이트 객체를 전달받아 사과 조건 검사를 캡슐화했다. 

 

- 73p 

 

 

컬렉션 탐색 로직과 각 항목에 적용할 동작을 분리할 수 있다는 것이 동작 파라미터화의 강점이다. 

- 75p 

 

 

소환 예시 

List<Apple> redAndHeavyApples = filterApples(inventory, new AppleRedAndHeavyPredicate()));

-74p

 

 

람다식 사용하기 

 

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

- 81p

 

 

 

리스트 형식으로 추상화 시키기 

public interface Predicate<T> {
	boolean test(T t);
}

public static <T> List<T> filter(List<T> list, predicate<T> p) {
	List<T> result = new ArrayList<>();
    for (T e: list){
      if (p.test(e)) {
       result.add(e);
     }
  return result;
}

-82p 

 

 

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

Comparator를 구현해서 sort 메서드의 동작을 다양화할 수 있다. 예를 들어 익명 클래스를 이용해서 무게가 적은 순서로 목록에서 사과를 정렬할 수 있다.

 

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

 

람다 표현식 

inventory.sort(
	(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));

- 83 ~ 84p 

 

 

반응형