일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 스트림
- spring Batch
- Stream
- Java8
- spring boot
- AWS101
- Java 8 in action
- Design Pattern
- Java
- 자바8
- Clean Code
- web
- 클린코드
- 자바의 신
- ddd
- Template Method Pattern
- domain
- Java8 in action
- 디자인 패턴
- Java in action
- 패스트캠퍼스
- head first
- 자바8인액션
- jsp
- spring
- facade pattern
- 자바
- CQRS
- Was
- SERVLET
- Today
- Total
주난v 개발 성장기
[자바 8 인 액션] 2장. 동작 파라미터화 코드 전달 본문
우리의 요구사항은 언제나 바뀐다.
"동작 파라미터화"를 이용하면 효과적으로 대응할 수 있다.
"동작 파라미터화"란 아직 어떻게 실행될지 정해지지 않은 코드 블록으로, 실행은 나중으로 미뤄진다.
이미 파일 필터링이나, List 정렬 등을 통해 경험을 해보았을 수 있지만, 동작 파라미터화를 추가하려면 코드가 늘어난다.
이는 3장 람다 표현식을 통해 해소된다.
변화하는 요구사항에 대응하자!
1. 녹색 사과만 필터링하자.
public List<Apple> filterGreenApples(List<Apple> inventory) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if ("green".equals(apple.getColor()){
result.add(apple);
}
}
return result;
}
2. 빨간 사과도 필터링하고 싶은데..? -> 색을 파라미터화 하자.
public List<Apple> filterColorApples(List<Apple> inventory, String color) {
List<Apple> result = new ArrayList<>();
for (Apple apple : inventory) {
if (color.equals(apple.getColor()){
result.add(apple);
}
}
return result;
}
--> 무게를 필터링하고 싶다면, 파라미터로 무게를 넣어야 한다. (목록을 검색하고, 필터링 조건을 적용하는 부분의 코드가 대부분 중복)
DRY(Don't repeat yourself, 같은 것을 반복하지 말자)에 위배된다.
3. 가능한 모든 속성으로 필터링
public List<Apple> filterApples(List<Apple> inventory, String color, int weight, boolean flag) {
List<Apple> result = new ArrayList<>();
...중략
return result;
}
true, false는 무엇을 의미하며, 요구사항이 변경되었을 경우에는 어떻게 처리할 것인가..?
동작 파라미터화
사과의 어떤 속성에 기초해서 불린값을 반환하는 방법이 있다. 이와 같은 동작을 프레디케이트라고 한다.
public interface ApplePredicate {
boolean test (Apple apple);
}
public class AppleHeavyWeightPredicate implements ApplePredicate {
public boolean test(Apple apple) {
return apple.getWeight() > 150;
}
}
public class AppleGreenPredicate implements ApplePredicate {
public boolean test(Apple apple) {
return "green".equals(apple.getColor());
}
}
public 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;
}
ApplePredicate - 알고리즘 패밀리
AppleGreenColorPredicate, AppleHeavyWeightPredicate - 알고리즘
위 조건에 따라 filter 메서드가 다르게 동작한다. 이를 "전략 디자인 패턴"이라고 부른다.
전략 디자인 패턴
알고리즘(전략)을 캡슐화하는 알고리즘 패밀리를 정의해두고, 런타임 시에 알고리즘을 선택하는 기법
Predicate를 수정하여, 한 개의 파라미터로 다양한 동작을 할 수 있다.
하지만, 여러 클래스를 구현해서 인스턴스 화하는 과정이 거추장스러울 수 있다.(3장에서 해결)
이를 익명클래스로도 해결할 수 있다.
장점
- 코드의 양을 감소
- 클래스 선언과 인스턴스화를 동시에 할 수 있음.
- 즉석에서 필요한 구현을 만들어서 사용할 수 있음.
단점
- 코드가 너무 길다. 많은 공간을 차지
- 익숙하지 못하다?
따라서 이러한 부분은 람다 표현식을 이용해서 해소될 것이다.
람다식을 이용한다면..
List<Apple> result = filterApples(inventory, (Apple apple) -> "red".equals(apple.getColor());
public interface Predicate<T> {
boolean test(T t);
}
public List<T> filter(List<T> list, Predicate<T> p) {
List<T> result = new ArrayList<>();
for (T t : list) {
if (p.test(t)) {
result.add(t);
}
}
return result;
}
동작 파라미터화 패턴
동작을 코드로 캡슐화한 다음에 메서드로 전달해서 메서드의 동작을 파라미터화 한다.
- Comparator 정렬
inventory.sort(new Comparator<Apple>() {
public int compare(Apple a1, Apple a2) {
return a1.getWeight().compare(a2.getWeight());
}
});
inventory.sort(
(Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));
- Runnable 코드 블록 실행
- GUI 이벤트 처리
'개발 성장기 > JAVA' 카테고리의 다른 글
[자바 8인 액션] 4장. 스트림 소개 (0) | 2020.07.05 |
---|---|
[자바 8인 액션] 3장. 람다 표현식 (0) | 2020.07.01 |
[자바 8 인 액션] 1장. 자바 8을 눈여겨봐야 하는 이유 (0) | 2020.06.13 |
[자바의 신] 1 ~ 13장 (0) | 2019.12.08 |
String, StringBuilder, StringBuffer 차이 (0) | 2019.11.14 |