-
[EffectiveKotlin] 상속보다는 컴포지션을 사용하라언어/Kotlin 2022. 6. 1. 01:00반응형
컴포지션이란
객체를 프로퍼티로 갖고, 함수를 호출하는 형태로 재사용하는 것이다.
컴포지션 구현
새로운 Set을 만들어 add와 addAll만 구현해야 한다고 가정해보자.
1. HashSet을 상속하지 않고, 컴포지션으로 구현하자
class CounterSet<T> { private val innerSet = HashSet<T>() var elemenetsAdded: Int = 0 private set fun add(element: T) { elementsAdded++ innerSet.add(element) } fun addAll(elements: Collection<T>) { elementsAdded += elementes.size innerSet.addAll(elements) } }
위 코드는 컴포지션을 이용해 HashSet의 add와 addAll을 구현했다. 하지만 CounterSet은 더 이상 Set으로 취급되지 않는다.
2. 위임패턴을 이용하자
위임패턴은 CounterSet에 MutableSet 인터페이스를 상속한다. 컴포지션만 사용했을 때 Set으로 취급되지 않는 단점을 보완할 수 있다.
class CounterSet<T>: MutableSet<T> { private val innerSet = HashSet<T>() var elemenetsAdded: Int = 0 private set override fun add(element: T) { elementsAdded++ innerSet.add(element) } override fun addAll(elements: Collection<T>) { elementsAdded += elementes.size innerSet.addAll(elements) } override fun contains(element: T): Boolean = innerSet.contains.containsAll(elements) override fun containsAll(element: Collection<T>): Boolean = innerSet.containsAll(elements) override fun ... override fun ... override fun ... . . . }
단점으로 add와 addAll 뿐아니라 인터페이스의 모든 함수를 구현해야 한다. 구현된 함수를 포워딩 메서드라고 한다.
3. Kotlin의 위임패턴 문법을 이용하자.
kotlin의 위임패턴 문법을 사용하면, 컴파일 시점에 포워딩 메서드를 자동으로 만들어준다.
class CounterSet<T>( private val innerSet<T> = mutableSetOf() ): MutableSet<T> by innerSet { var elemenetsAdded: Int = 0 private set override fun add(element: T) { elementsAdded++ innerSet.add(element) } override fun addAll(elements: Collection<T>) { elementsAdded += elementes.size innerSet.addAll(elements) } }
4. 상속보다는 컴포지션을 사용하는게 낫지만, 아닌경우도 있다.
- 상속은 슈퍼클래스의 모든 단위 테스트를 서브클래스로도 통과할 수 있어야 할때 사용하는 것이 좋다. 즉, B가 A의 자식일 때, A타입을 사용하는 부분에서 B로 치환해도 문제없이 동작한다. (리스코프 치환의 법칙)
반응형'언어 > Kotlin' 카테고리의 다른 글
[properties, env] 자바에서 시스템 환경변수 읽어오기 (0) 2024.04.20 [EffectiveKotlin] equals, hashcode 규약과 data class, jpa (0) 2022.06.01 [Kotlin in Action, Effective Kotlin] 제네릭과 변성 variance (0) 2022.05.29 [Kotlin] - List의 합집합, 차집합, 교집합 (0) 2022.05.08 [Kotlin In Action] 객체의 동등성: equals()와 해시 컨테이너: hashCode() 그리고 data class (0) 2022.04.26