컴포지트 패턴이란?
개요
프로그래밍을 하면서 컴포지트 패턴을 종종 활용하곤 했습니다.
컴포지트 패턴에 대해 조금 더 자세하게 알아보고 이해해보고자 합니다.
Composite 뜻
Composite는 복합, 합성이라는 의미를 가집니다.
복잡 재료라고 하면 한 가지 물질로 이루어지지 않고 단독 재료로는 얻을 수 없는 특성을 지니도록 합니다.
디자인패턴 관점에서 생각해 보면 여러 객체들을 복합적으로 구성한다고 생각할 수 있습니다.
해결하는 문제
상자에 여러가지 물체들이 있다고 생각해 보겠습니다.
이때 상자의 가격을 얻기 위해서는 각 물품들이 어떻게 가격이 구성되는지 계산하여 다 더해야 합니다.
현실에서는 모든 상자를 풀고 가격을 측정하면 되지만 프로그래밍적으로는 상자 안에 또 상자가 있을지 각 가격에 대해 계산이 필요하기 때문에 가격을 측정하기 어려울 수 있습니다.
해결방법
가격을 계산하는 공통 인터페이스를 통하여 가격의 계산은 각자의 클래스(제품 or 상자)에서 처리합니다.
최초에 객체가 가격을 물어보면 하위 객체들이 가격을 알아서 가져오게 됩니다.
객체의 구조
1. Component라는 인터페이스를 두게 됩니다.
구현할 때 ItemCalculator라는 이름이 될 것 같습니다.
2. Leaf는 해당 Component 인터페이스를 구현합니다.
구현할 때 HammerItemCalculator, PhoneItemCalculator 등의 이름으로 구현될 것 같습니다.
3. Composite는 Component 인터페이스를 구현하며, 여러 Leaf를 실제로 호출하는 역할을 수행합니다.
구현할 때 ItemCalculatorComposite라는 이름이 될 것 같습니다.
4. Client는 Composite를 제어합니다.
구현해 보기
Spring framework와 Kotlin 언어를 활용하여 컴포지트 패턴을 구현해보고자 합니다.
interface ItemCalculator {
fun calculatePrice(): Long
}
ItemCalculator 인터페이스를 선언하고 가격을 가져오기 위한 메서드를 정의합니다.
Component의 역할을 수행합니다.
@Component
class HammerItemCalculator: ItemCalculator {
override fun calculatePrice(): Long {
return HAMMER_PRICE
}
}
const val HAMMER_PRICE = 10_000L
망치의 가격을 계산하여 가져오는 Leaf입니다.
@Component
class PhoneItemCalculator: ItemCalculator{
override fun calculatePrice(): Long {
return PHONE_PRICE
}
}
const val PHONE_PRICE = 100_000L
휴대전화의 가격을 계산하여 가져오는 Leaf입니다.
@Component
class ItemCalculatorComposite(
private val itemCalculator: List<ItemCalculator>
): ItemCalculator {
override fun calculatePrice(): Long {
return itemCalculator.sumOf { it.calculatePrice() }
}
}
Composite는 Leaf를 Children으로 가지고 있으며 실제 자식들에게 계산을 위임하고 총합만 전달합니다.
@Component
class CompositeClient(
private val itemCalculatorComposite: ItemCalculatorComposite,
): ApplicationRunner {
override fun run(args: ApplicationArguments) {
val price = itemCalculatorComposite.calculatePrice()
println("총 가격은 : $price 입니다") // 110000원 출력
}
}
Client는 Composite를 통하여 가격을 조회할 수 있습니다.
참고자료
https://en.wikipedia.org/wiki/Composite_pattern
https://ko.wikipedia.org/wiki/%EB%B3%B5%ED%95%A9_%EC%9E%AC%EB%A3%8C
https://refactoring.guru/ko/design-patterns/composite