소스코드
https://github.com/mjung1798/Jyami-Java-Lab/tree/master/java8-in-action
동작 파라미터화 : 아직은 어떻게 실행할 것인지 결정하지 않은 코드 블록, 코드 블록의 실행은 나중으로 미뤄진다.
변화하는 요구사항에 유연하게 대응할 수 있게 코드를 구현하는 방법
- 리스트의 모든 요소에 '어떤 동작'을 수행할 수 있음
- 리스트 관련 작업을 끝낸 다음에 '어떤 다른 동작'을 수행할 수 있음
- 에러가 발생하면 '정해진 어떤 다른 동작'을 수행할 수 있음
1. 변화하는 요구사항에 대응하기
DRY(don't repeat yourself) : 같은 것을 반복하지 말것.
문자열, 정수, 불린 등의 값으로 메서드를 파라미터화 할 때 => 한줄이 아니라 메서드 전체 구현을 바꾸어야 한다.
녹색 사과 필터링
filterGreenApples(List<Apple> inventory)
-> 색에 따른 필터링filterApplyByColor(List<Apple> inventory, String color)
-> 속성 필터링filterApples(List<Apple> inventory, String color, int wieght, boolean flag)
별로다
2. 동작 파라미터화
프레디케이트 Predicate
: 선택 조건을 결정하는 인터페이스 => 어떤 속성에 기초해서 불린값을 반환
전략 디자인 패턴(strategy design pattern)
- 각 알고리즘(전략이라 불리는)을 캡슐화하는 알고리즘 패밀리를 정의해둔 다음에 런타임에 알고리즘을 선택하는 기법
- 객체가 할 수 있는 행위를 전략으로 만들고 동적으로 행위의 수정이 필요한 경우 전략으로 바꾸는 것만으로도 행위의 수정이 가능하도록 만든 패턴
public interface ApplePredicate{
boolean test(Apple apple);
}
public class AppleGreenColorPredicate implements ApplePredicate {
@Override
public boolean test(Apple apple) {
return "green".equals(apple.getColor());
}
}
public class AppleHeavyWeightPredicate implements ApplePredicate{
@Override
public boolean test(Apple apple) {
return apple.getWeight() > 150;
}
}
동작 파라미터화 : 메서드가 다양한 동작(전략)을 받아서 내부적으로 다양한 동작을 수행한다.
public static List<Apple> filterApples(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> heavyApples = FilteringApple.filterApples(inventory, new AppleHeavyWeightPredicate());
List<Apple> greenApples = FilteringApple.filterApples(inventory, new AppleGreenColorPredicate());
내가 전달한 ApplePredicate 객체에 의해 filterApples 메서드의 동작이 결정된다.
한 메서드가 다른 동작을 수행하도록 재활용이 가능하다 : 한개의 파라미터 다양한 동작
3. 간소화 하기
a. 익명 클래스
익명클래스(anonymous class) 기법 : 클래스의 선언과 인스턴스화를 동시에 수행할 수 있는 기법
클래스 선언과 인스턴스화를 동시에 할 수 있다 == 즉석에서 필요한 구현을 만들어서 사용할 수 있다.
Predicate 인터페이스를 구현하는 클래스 만들어서 인스턴스 화 해야한다 (귀찮음)
List<Apple> redApples = FilteringApple.filterApples(inventory, new ApplePredicate() {
@Override
public boolean test(Apple apple) {
return "red".equals(apple.getColor());
}
});
assertThat(redApples.size()).isEqualTo(2);
그러나 장황하다 : 나쁘다!
람다 표현식으로 코드를 더 간결하게 정리할 수 있다.
b. 람다 표현식
List<Apple> redApples = FilteringApple.filterApples(inventory, apple -> "red".equals(apple.getColor()));
유연함과 간결함 두가지를 모두 가져간다!
c. 형식 파라미터를 이용한 추상화
public static <T> List<T> filter(List<T> list, Predicate<T> p){
List<T> result = new ArrayList<>();
for(T e: list){
if(p.test(e))
result.add(e);
}
return result;
}
d. 종합: 동작 파라미터화의 3가지 방법
- 클래스
- 익명 클래스
- 람다
5. 실전 예제
a. Comparator 정렬
sort 동작을 파라미터화 할 수 있다.
// 익명클래스 이용
inventory.sort(new Comparator<Apple>() {
@Override
public int compare(Apple o1, Apple o2) {
return o1.getWeight().compareTo(o2.getWeight());
}
});
// 람다식 이용
inventory.sort((a1, a2)->a1.getWeight().compareTo(a2.getWeight()));
b. Runnable 코드 블록 실행
// 익명클래스 이용
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("helloWorld");
}
});
t1.run();
// 람다식 이용
Thread t2 = new Thread(() -> System.out.println("helloWorld"));
t2.run();
'Dev Book Review > Java8 in Action' 카테고리의 다른 글
[자바8인액션] Chap17. 리액티브 프로그래밍 (1) | 2021.01.10 |
---|---|
[자바8인액션] Chap15. CompletableFuture와 리액티브 프로그래밍 컨셉의 기초 (2) | 2021.01.10 |
[자바8인액션] Chap.3 람다 표현식 (0) | 2020.07.30 |
[자바8인액션] Chap.1 자바 8을 눈여겨 봐야하는 이유 (0) | 2020.07.29 |