ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 컴포지트 패턴이란?
    디자인패턴 2024. 2. 26. 00:01

    개요

    프로그래밍을 하면서 컴포지트 패턴을 종종 활용하곤 했습니다.

    컴포지트 패턴에 대해 조금 더 자세하게 알아보고 이해해보고자 합니다.

     

    Composite 뜻

    Composite는 복합, 합성이라는 의미를 가집니다.

    복잡 재료라고 하면 한 가지 물질로 이루어지지 않고 단독 재료로는 얻을 수 없는 특성을 지니도록 합니다.

    디자인패턴 관점에서 생각해 보면 여러 객체들을 복합적으로 구성한다고 생각할 수 있습니다.

     

    해결하는 문제

    https://refactoring.guru/ko/design-patterns/composite

    상자에 여러가지 물체들이 있다고 생각해 보겠습니다.

    이때 상자의 가격을 얻기 위해서는 각 물품들이 어떻게 가격이 구성되는지 계산하여 다 더해야 합니다.

     

    현실에서는 모든 상자를 풀고 가격을 측정하면 되지만 프로그래밍적으로는 상자 안에 또 상자가 있을지 각 가격에 대해 계산이 필요하기 때문에 가격을 측정하기 어려울 수 있습니다.

     

    해결방법

    https://refactoring.guru/ko/design-patterns/composite

     

    가격을 계산하는 공통 인터페이스를 통하여 가격의 계산은 각자의 클래스(제품 or 상자)에서 처리합니다.

    최초에 객체가 가격을 물어보면 하위 객체들이 가격을 알아서 가져오게 됩니다.

     

    객체의 구조

    https://refactoring.guru/ko/design-patterns/composite

     

    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

     

     

    '디자인패턴' 카테고리의 다른 글

    Adaptor 패턴이란?  (0) 2024.03.07
    Delegate Pattern이란  (0) 2024.03.03
    템플릿 메소드 패턴이란?  (0) 2024.02.10

    댓글

Designed by Tistory.