문제 상황
// 사과 목록을 필터링하는 예시
public static List<Apple> filterGreenApples(List<Apple> inventory) { ... }
public static List<Apple> filterHeavyApples(List<Apple> inventory)
해결 방법
public interface ApplePredicate {
boolean test(Apple apple);
}
public static List<Apple> filterApples(
List<Apple> inventory,
ApplePredicate predicate
) {
List<Apple> result = new ArrayList<>();
for(Apple apple : inventory) {
if(predicate.test(apple)) {
result.add(apple);
}
}
return result;
}
if/else 남발을 제거할 수 있음// 동작 파라미터화를 통해 이런 클래스가 다수 생성
class GreenApplePredicate implements ApplePredicate {
public boolean test(Apple apple) {
return "green".equals(apple.getColor());
}
}
익명 클래스를 사용List<Apple> greenApples =
filterApples(inventory, new ApplePredicate() {
@Override
public boolean test(Apple apple) {
return "green".equals(apple.getColor());
}
});
Comparator, Runnable, Callback공통 목적
Comparator
public interface Comparator<T> {
int compare(T o1, T o2);
}
Collections.sort(inventory, new Comparator<Apple>() {
@Override
public int compare(Apple a1, Apple a2) {
return a1.getWeight() - a2.getWeight();
}
});
Runnable
public interface Runnable {
void run();
}
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("작업 실행");
}
});
Callback
public interface Callback {
void call();
}
public void doSomething(Callback callback) {
// 작업 수행
callback.call(); // 작업 후 호출
}
doSomething(new Callback() {
@Override
public void call() {
System.out.println("작업 완료 후 실행");
}
});
제어의 역전(Inversion of Control)로 표현Callback은 언제 실행될지 모르는 로직을 미리 등록해두는 방식