동작 매개변수화
계속해 최소한의 비용으로 변화하는 요구에 지속적으로 대응수행은 프로그래머에게 중요한 요소입니다.
작동 매개변수화를 통해 이러한 변화에 보다 쉽게 대응할 수 있습니다. 이런 이유로 손쉬운 유지 보수잃다
이동을 매개변수화하는 기능
- 목록의 각 항목에 대해 “무슨 행동”. 할 수있어
- 목록 작성을 마친 후 ‘다른 행동’가능하다
- 오류가 발생했을 때 `다른 지정된 작업` 할 수있어
아래는 실제 책의 예입니다.
(If: 녹색인 경우에만 수집)
public static List<Apple> filterGreenApples(List<Apple> inventory) {
List<Apple> result new ArrayList<>();
for (Apple apple : inventory) {
if (apple.getColor() == Color.GREEN) {
result.add(apple);
}
}
return result;
}
위와 같이 작성했는데 요구사항이 변경되면 내부 조건문도 변경해야 합니다.
여기서 청사과가 아닌 다른 색상을 선택하고 싶다면
/**
* List<Apple> greenApples = filterApplesByColor(inventory, Color.GREEN); 으로 사용 가능
*/
public static List<Apple> filterGreenApples2(List<Apple> inventory, Color color) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if (apple.getColor() == color) {
result.add(apple);
}
}
return result;
}
위와 같이 매개변수화하여 변경할 수 있습니다. 하지만 만약 상태가 증가하고 일반화되면 이 부분을 매개변수화한 다음 매개변수의 수가 크게 증가합니다..
색상이 아닌 크기별로 이름을 지정하고 싶다면?
public static List<Apple> filterGreenApples3(List<Apple> inventory, int size) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if (apple.getWeight() == size) {
result.add(apple);
}
}
return result;
}
그렇게 바뀌고 둘 다 필요할 때 다시 바뀌기 때문에 유지 보수에 많은 돈을 먹습니다.
이 문제를 해결하기 위해 작업 parimization이 사용됩니다. 말 그대로 행동을 넘겨주는 것으로 생각할 수 있습니다.
interface ApplePredicate {
boolean test(Apple a);
}
// class 내부
public static List<Apple> filterGreenApples4(List<Apple> inventory, ApplePredicate p) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if (p.test(apple)) { // 필요한 메서드에 맞게 사용 가능
result.add(apple);
}
}
return result;
}
// 호출
List<Apple> redApples2 = filterGreenApples4(inventory, new ApplePredicate() {
@Override
public boolean test(Apple a) {
return a.getColor() == Color.RED;
}
});
이런 식으로 특정 클래스를 익명 클래스로 재정의하고 적절한 메서드를 실행합니다.
결과적으로 필요에 따라 재정의된 메서드의 기능을 변경합니다.할 수 있어요.
그러나 지금 문제있는 즉시 “익명의 클래스”.오전.
익명 클래스를 구현하기 위해서는 상속받을 인터페이스가 존재해야 하는데, 특정 기능별로 인터페이스를 구현하고 오버라이드하면 상당한 비용이 들고 유지보수가 어렵다.
그래서 사용 람다오전.
List<Apple> redApples2 = filterGreenApples4(inventory, Apple apple -> apple.getColor() == Color.RED)
List<Apple> redApples2 = filterGreenApples4(inventory, Apple apple -> apple.getWeight() > 150)
Lambda를 통해 인터페이스를 구현하지 않고 위와 같이 변경할 수 있습니다.