클래스 delegation (컴포지션, composition)

  • 상속을 허용하지 않는 클래스에 새로운 동작을 추가해야 할 때(Wrapping) 또는 메소드의 동작을 변경하고 싶을 때 위임을 사용하게 되는데 단점이 준비 코드가 너무 많이 필요하다는 점이다.
  • 아래와 같이 `` innerList``를 Wrapping하게 되면 위와 같이 굳이 재정의하고 싶지 않은, 단순히 원래 클래스로 전달하고 싶은 코드도 모두 재정의해야 하기 때문에 상당히 난잡해진다.

```kt

class DelegatingCollection0<T>(

        private val innerList: ArrayList<T> = arrayListOf<T>()

) : Collection<T> {

 

    override val size: Int get() = innerList.size

    override fun isEmpty() : Boolean = innerList.isEmpty()

    override fun contains(element: @UnsafeVariance T): Boolean =

            innerList.contains(element)

    override fun iterator(): Iterator<T> = innerList.iterator()

    override fun containsAll(elements: Collection<@UnsafeVariance T>): Boolean =

            innerList.containsAll(elements)

}

```

 

 

by 키워드를 사용하면 이를 자동으로 처리해준다!

```kt

class CountingSet<T>(

        private val innerSet: MutableCollection<T> = HashSet<T>()

) : MutableCollection<T> by innerSet {

 

    var objectsAdded = 0

 

    override fun add(element: T): Boolean {

        objectsAdded++

        return innerSet.add(element)

    }

    override fun addAll(elements: Collection<T>): Boolean {

        objectsAdded += elements.size

        return innerSet.addAll(elements)

    }

}

 

// 반드시 생성자에서 받을 필요는 없다.

@Component

class LocalOrderBookContainer private constructor(

    private val applicationEventPublisher: ApplicationEventPublisher,

    private val container: ConcurrentHashMap<String, OrderBook>

) : ConcurrentMap<String, OrderBook> by container {

// 여기서 Map<>으로 설정하면, Map 인터페이스가 된다!

 

    @Autowired constructor(

        applicationEventPublisher: ApplicationEventPublisher

    ): this(applicationEventPublisher, ConcurrentHashMap<String, OrderBook>())

```

 

  • delegation 대상이 될 필드는 val 이어야 한다. (var는 불가)
  • delegation 타입을 어떻게 설정하느냐에 따라 외부 인터페이스를 다르게 줄 수 있다.
  • 기능을 변경하고 싶은 메소드만 명시적으로 오버라이드하면 된다.
  • 명시적으로 오버라이드된 메소드가 있을 경우 그 메소드가 호출되고, 오버라이드 하지 않은 메서드는 같은 이름의 innerSet 메서드로 연결된다.
  • https://medium.com/til-kotlin-ko/kotlin의-클래스-위임은-어떻게-동작하는가  

 

프로퍼티 delegation