728x90
  • 우리가 어떤 상황에서 일을 하든 소비자 요구사항은 항상 바뀐다.
  • ⇒ 변화하는 요구사항은 불가피한 문제

 

❓변화하는 요구사항의 대처

  • 엔지니어링적인 비용 최소화
    • 새로 추가한 기능 → 쉽게 구현
    • 장기적인 관점 → 유지보수 용이

 

  • 동작 파라미터화(behavior parameterization)
    • 자주 바뀌는 요구사항에 효과적으로 대응
    • 아직은 어떻게 실행할 것인지 결정하지 않은 코드 블록⇒ 코드 블록의 실행은 나중으로 미뤄진다.
    • ⇒ 나중에 프로그램에서 호출
    • e.g. 나중에 실행될 메서드의 인수로 “코드 블록”을 전달

 

⭐ 메서드의 동작이 파라미터화된다.

- 리스트의 모든 요소에 대해서 ‘어떤 동작’을 수행
- 리스트의 관련 작업을 끝낸 다음에 ‘어떤 다른 동작’을 수행할 수 있음
- 에러가 발생하면 ‘정해진 어떤 다른 동작’을 수행할 수 있음

 

2.1 변화하는 요구사항에 대응하기

2.1.1 첫 번째 시도 : 녹색 사과 필터링

  • e.g. 기존 농장 재고 목록 애플리케이션에 리스트에서 녹색 사과만 필터링
enum Color { RED, GREEN }

public static List<Apple> filterGreenApples(List<Apple> inventory) {
    List<Apple> result = new ArrayList<>(); // 사과 누적 리스트
    for (Apple apple: inventory) {
            if (GREEN.equals(apple.getColor()) { // 녹색 사과만 선택
                    result.add(appled);
            }
        }
        return result;
}

⇒ ✨ 새로운 요구사항

  • 녹색 사과말고 빨간 사과 필터링을 원함
  • 메서드 복제를 통한 반복 코드 추상화

 

2.1.2 두 번째 시도 : 색을 파라미터화

  • 코드를 반복 사용하지 않고 filterRedApples 구현
    • 색을 파라미터화 할 수 있도록 메서드에 파라미터 추가
publc static List<Apple> filterApplesByColor(List<Apple> inventory, Color color)
{
    List<Apple> result = new ArrayList<>();
    for (Apple apple: inventory) {
        if (apple.getColor().equals(color) ) {
                result.add(appled);
        {
    }
    return result;
}
List<Apple> greenApples = filterApplesByColor(inventory, GREEN);
List<Apple> redApples = filterApplesByColor(inventory, RED);

👉🏻 Color를 가져와서 필터링 조건에 적용한다.

 

  • 무게 조건의 추가
    • 새로운 요구사항으로 ‘가벼운 사과’ & ‘무거운 사과’ 구분에 대한 요구
public statuc List<Apple> filterApplesByWeight(List<Apple> inventory, int weight)
{
        List<Apple> result = new ArrayList<>();
        for (Apple apple: inventory) {
                if (apple.getWeight() > weight) {
                        result.add(apple);
                }
        }
        return result;
}
  • 목록 검색 → “사과에 필터링 조건 적용”
    • ❌ 색 필터링 코드와 중복됨
    • 💡 ”DRY (Don’t Repeat Yourself)” 의 위반

 

2.1.3 세 번째 시도 : 가능한 모든 속성으로 필터링

  • ❌ 모든 속성을 메서드 파라미터로 추가
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) ||
                (!flag && apple.getWeight() > weight)) {
                    result.add(apple);
        }
    }
    return result;
}
  • 형편없는 코드
  • flag : 의미적 불명확성
    • 요구사항 변화에 따른 유연한 대응 불가

 

2.2 동작 파라미터화

  • 요구사항에 유연하게 대응하기 위한 방법
  • Predicate
    • 참 또는 거짓을 반환하는 함수 → ✨ 선택 조건을 결정하는 인터페이스 정의 ✨
public interface ApplePredicate {
        boolean test (Apple apple);
}
  • 선택조건 predicate 로 처리

 

public class AppleHeavyWeightPredicate implements ApplePredicate {
        public boolean test(Apple apple) {
                return apple.getWeight() > 150;
        }
}
  • predicate 무게 옵션 구현체

 

public class AppleGreenColorPredicate implements ApplePredicate {
        public boolean test(Apple apple) {
                return GREEN.equals(apple.getColor());
        }
}
  • predicate 색상 옵션 구현체

 

  • ApplePredicate → 사과 선택 전략을 캡슐화 한다.
    • 전략 디자인 패턴
    • 각 알고리즘(전략)을 캡슐화하는 알고리즘 패밀리를 정의해둔 뒤 런타임에 알고리즘을 선택하는 기법
      • ApplePredicate → 알고리즘 패밀리
      • AppleHeavyWeightProdicate , AppleGreenColorPrediate → 전략

 

🧐 ApplePredicate 가 어떻게 다양한 동작을 수행할 수 있는가?

  • filterApples 에서 ApplePredicate 객체를 받아서 애플의 조건을 검사하도록 메서드 수정
  • ⇒ 동작 파라미터화 : 메서드가 다양한 동작을 받아서 내부적으로 다양한 동작 수행
728x90