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
'📖 Book' 카테고리의 다른 글
[모던 자바 인 액션] 1. 자바 8, 9, 10, 11 : 무슨 일이 일어나고 있는가? (61) | 2024.01.25 |
---|---|
[헤드 퍼스트 디자인 패턴] 1. 전략 패턴 (0) | 2024.01.15 |
[구글 엔지니어는 이렇게 일한다] Overview (0) | 2022.08.08 |