오늘도 더 나은 코드를 작성하였습니까?

전략패턴(Strategy Pattern) 본문

디자인패턴

전략패턴(Strategy Pattern)

hik14 2022. 7. 11. 01:08

정의

 실행 중에 알고리즘을 선택할 수 있게 하는 행위 소프트웨어 디자인 패턴이다. 다른 말로 정책패턴이라 부른다.

  • 특정한 계열의 알고리즘들을 정의
  • 각 알고리즘(특정 행동에 관한 알고리즘)을 캡슐화
  • 이 알고리즘들을 해당 계열 안에서 상호 교체가 가능하게 한다.

 

*Context

- 상황, 맥락, 문맥

- 개발자가 특정 작업을 완료하는데 있어서 필요한 모든 관련된 정보

 

결제 시스템

 

data class Item(
    val id: Int,
    val name: String,
    val price: Int
)

class ShoppingCart {

    private val _itemList: MutableList<Item> = arrayListOf()
    val itemList: List<Item>
        get() = _itemList

    fun add(item: Item) =
        _itemList.add(item)

    fun remove(item: Item) =
        _itemList.remove(item)

    fun show() =
        "${_itemList.joinToString()} in cart"

    fun totalPrice() = _itemList.sumOf { it.price }
}

1. 분기를 통한 해결   if...else if 

class PlaceOrder(
    val address: String,
    val cart: ShoppingCart,
) {
    fun payment(
        method: Int,
        point: Point? = null,
        account: Account? = null, 
        card: Card? = null, 
        phone: Phone? = null
    ) {
        val price = cart.totalPrice()

        if (method == 1) {
            // 포인트 충전결제
        } else if (method == 2) {
            // 계좌 간편결제
        } else if (method == 3) {
            // 카드 간편결제
        } else if (method == 4) {
            // 일반 결제
            if (method == 5) {
                // 신용카드
            } else if (method == 6) {
                // 휴대폰
            } else if (method == 7) {
                // 나중에 결제
            }
        }
    }
}

fun main() {

    val cart = ShoppingCart()
    cart.add(Item(1, "초콜렛", 1000))
    cart.add(Item(2, "음료수", 1000))

    println(cart.show())

    PlaceOrder(address = "우리집", cart = cart).payment(........)
}

2. 상속을 통한 해결 ???

 

명확한  변경되지 않는 계층 구조가 보이지 않을때 어설프게 상속을 사용하면 추후에 유지보수에 있어 매우 힘들어지기 때문에 되로록이면 상속을 함부로 사용하면 안된다.

 

3. 전략 패턴을 이용한 해결

interface PaymentTool {
    fun pay(price: Int)
}

class Point : PaymentTool {
    override fun pay(price: Int) {
        TODO("Not yet implemented")
    }
}

class Account : PaymentTool {
    override fun pay(price: Int) {
        TODO("Not yet implemented")
    }
}

class Card : PaymentTool {
    override fun pay(price: Int) {
        TODO("Not yet implemented")
    }
}

class Phone : PaymentTool {
    override fun pay(price: Int) {
        TODO("Not yet implemented")
    }
}
class PlaceOrder(
    val address: String,
    val cart: ShoppingCart,
    var paymentTool: PaymentTool
) {

    fun payment() {
        val price = cart.totalPrice()
        paymentTool.pay(price)
    }
    
    fun selectPaymentTool(tool: PaymentTool){
        paymentTool = tool
    } 
}

 

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

느슨한 결합과 강한 결합  (0) 2022.07.18
Observer pattern(옵저버 패턴)  (0) 2022.07.18
Dependency Inversion Principle  (0) 2021.12.28
Interface Segregation  (0) 2021.12.28
리스코프 치환법칙(Liskov Substitution)  (0) 2021.12.28