대부분의 프로그래밍 언어에는 함수 타입이라는 개념이 없습니다. 그래서 연산 또는 액션을 전달할 때 메서드가 하나만 있는 인터페이스를 활용합니다. 이러한 인터페이스를 SAM(Single-Abstract Method)이라고 부릅니다.
(SAM의 장점은 Argument에 이름이 붙다는 장점이 있습니다.)
interface OnClick {
fun clicked(view: View)
}
SAM형태로 사용하는 코드를 아래와 같이 함수 타입을 사용하는 코드로 변경하면, 더 많은 자유를 얻을 수 있습니다.
fun setOnClickListener(listener: (View) -> Unit) {
// ...
}
SAM과 마찬가지로 타입 별칭(type aliase)를 사용하면 함수 타입도 이름을 붙일 수 있습니다.
(별칭을 붙이면, IDE의 지원을 받을 수 있습니다.)
typealias OnClick = (view) -> Unit
람다 표현식을 사용할 때는 아규먼트 분해(destructure argument)도 사용할 수 있습니다.
고전적인 자바는 아래와 같이 인터페이스를 기반으로 구현했습니다.
class CalendarView {
var listener: Listener? = null
interface Listener {
fun onDateClicked(date: Date)
fun onPageChanged(date: Date)
}
}
하지만 API를 소비하는 사용자의 관점에서는 함수 타입을 따로따로 갖는 것이 훨씬 사용하기 쉽습니다.
class CalendarView {
var onDateClicked: ((date: Date) -> Unit)? = null
var onPageChanged: ((date: Date) -> Unit)? = null
}
이렇게 onDateClicked와 onPageChanged를 한거번에 묶지 않으면, 각각의 것을 독립적으로 변경할 수 있다는 장점이 생깁니다.
인터페이스를 사용해야 하는 특별한 이유가 없다면, 함수 타입을 활용하는 게 좋습니다. 함수 타입은 다양한 지원을 받을 수 있으며, 코틀린 개발자들 사이에서 이미 널리 사용되고 있습니다.
언제 SAM을 사용해야 할까?
딱 한 가지 Kolin이 아닌 다른 언어에서 사용할 클래스를 설계할 때 SAM을 사용하는 것이 좋습니다. 자바에서는 인터페이스가 더 명확합니다. 함수 타입으로 만들어진 클래스는 자바에서 타입 별칭과 IDE의 지원등을 제대로 받을 수 없습니다. 마지막으로 다른 언어에서 코틀린의 함수 타입을 사용하려면 Unit을 명시적으로 리턴하는 함수가 필요합니다.
interface OnDateClicked {
fun onClick(date: Date)
}
class CalendarView() {
var onDateClicked: ((date: Date) -> Unit)? = null
var onPageChanged: OnDateClicked? = null
}
CalendarView c = new CalendarView();
c.setOnDateClicked(date -> Unit.INSTANCE);
c.setOnPageChanged(date -> {});
'Kotlin' 카테고리의 다른 글
[Effective Kotlin] 40 - equals의 규약을 지켜라 (0) | 2023.10.29 |
---|---|
[Effective Kotlin] 39 - 태그 클래스보다는 클래스 계층을 사용하라 (0) | 2023.10.22 |
[Effective Kotlin] 37 - 데이터 집합 표현에 data 한정자를 사용하라 (0) | 2023.10.08 |
[Effective Kotlin] 36 - 상속보다는 컴포지션을 사용하라 (0) | 2023.10.02 |
[Effective Kotlin] 35 - 복잡한 객체를 생성하기 위한 DSL을 정의하라 (0) | 2023.09.24 |