Skip to content

Latest commit

 

History

History
144 lines (101 loc) · 3.92 KB

동작파라미터화코드전달하기.md

File metadata and controls

144 lines (101 loc) · 3.92 KB

동작 파라미터화 코드 전달하기

Behavior Parameterization

동작 파라미터화. 아직은 어떻게 실행할 것인지 결정하지 않은 코드 블록. 이 코드 블록은 나중에 프로그램에서 호출함.

자주 바뀌는 요구사항에 효과적으로 유연하게 대응할 수 있음.


예제

사과를 filter함.

1. 프레디케이트 함수로, 선택 조건을 결정하는 인터페이스를 정의한다.

public interface ApplePredicate {
    boolean test(Apple apple);
}

ApplePredicate는 사과 선택 전략을 캡슐화 한다.


2. 다양한 선택 조건을 대표하는 여러 버전의 ApplePredicate를 정의할 수 있다.

public class AppleHaveyWeightPredicate implements ApplePredicate {
    
    @Override
    public boolean execute(Apple apple) {
        return apple.getWeight() > 150;
    }
}
public class AppleGreenColorPredicate implements ApplePredicate {
    
    @Override
    public boolean execute(Apple apple) {
        return GREEN.equals(apple.getColor());
    }
}

이는 전략 디자인 패턴으로 볼 수 있다.

각 알고리즘(=전략)을 캡슐화 하는 알고리즘 패밀리를 정의해둔 다음에, 런타임에 알고리즘을 선택하는 기법이다.


3. 추상적 조건으로 필터링한다.

public static List<Apple> filterAppes(List<Apple> inventory, ApplePredicate p) {
    List<Apple> result = new ArrayList<>();
    if(p.execute(apple)) {
        result.add(apple);
    }

    return result;
}

이렇게 동작 파라미터화, 즉 메서드가 다양한 동작(또는 전략)을 받아서 내부적으로 다양한 동작을 수행할 수 있다.



복잡한 과정 간소화

위 예제에서 보이는 바와 같이, 새로운 동작은 전달하려면 인터페이스를 만들고, 이를 구현하는 여러 클래스를 정의한 뒤, 인스턴스화해야 한다. 이는 상당히 번거롭다.


익명 클래스로 간소화

말 그대로 이름이 없는 클래스이다. 클래스 선언과 인스턴스화를 동시에 할 수 있다.

List<Apple> redApples = filterApples(inventory, new ApplePredicate() {
    public boolean execute(Apple apple) {
        return RED.equals(apple.getColor());
    }
})

람다 표현식으로 간소화

익명 클래스도 여전히 버겁다. 람다를 통해 간단하게 구현할 수 있다.

List<Apple> result = filterApples(inventory, (Apple apple) -> RED.equals(apple.getColor()));

동작 파라미터화와 값 파라미터화

image

Generic을 이용하여 type에도 유연하게 만들면 좋다. (= 형식 파라미터)



실전 예제

자바 API의 많은 메서드를 다양한 동작으로 파라미터화 할 수 있다.


Comparator로 정렬하기

자바 8의 List에는 sort 메서드가 포함되어 있다. 다음과 같은 인터페이스를 갖는 java.util.Comparator 객체를 이용해서 sort의 동작을 파라미터화 할 수 있다.

// java.util.Comparator
public interface Comparator<T> {
    int compare(T o1, T o2);
}

-> 사과 무게로 정렬하기

inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight()));

Runnable로 코드 블록 실행하기

자바 스레드를 이용하면 병렬로 코드 블록을 실행할 수 있다. 어떤 코드를 실행할 것인지를 스레드에게 알려주면 된다. 이때 Runnable 인터페이스를 이용해 실행할 코드 블록을 지정할 수 있다.

// java.lang.Runnable
public interface Runnable {
    void run();
}

-> 구현하기

Thread t = new Thread(() -> System.out.println("hello world!"));

이외에도 Callable, GUI event 처리 등을 예로 들 수 있다.