디자인패턴

리스코프 치환법칙(Liskov Substitution)

hik14 2021. 12. 28. 11:53

치환성은 객체 지향 프로그래밍의 원칙이다. 컴퓨터 프로그램에서 자료형 S가 자료형T의 하위타입이라면 수정을 거치지 않고, 자료형T의 객체를 자료형S의 객체로 교체하여도 기존의 나머지 부분들과 충돌없고, 오류 없이 실행되어야 한다.

import java.util.*

fun main() {

    val sCard  = SCard("13579")
    val spCard  = SCardPlus("246810")

    val shop = Shop()

    shop.addBeverage()
    shop.addSnack()
    
    println(shop.order(sCard))
    println(shop.order(spCard))
}

abstract class Card(val number: String){

    abstract fun payment(company: String, amount: Int): Receipt
}

open class SCard(number: String): Card(number){
    override fun payment(company: String, amount: Int): Receipt = Receipt(company, Date(), amount)
}

class SCardPlus(number: String): SCard(number){

    var totalPoint: Int = 0

    override fun payment(company: String, amount: Int): Receipt{
        val point =  (amount / 10)
        totalPoint = point + (amount / 10)
        println("point+ $point")
       return Receipt(company, Date(), amount)
    }
}

class Receipt(
    private val company: String,
    private val date: Date,
    private val amount: Int,
){
    override fun toString(): String {
        return "Receipt(company='$company', date=$date, amount=$amount)"
    }
}

class Shop{

    private var totalAmount: Int = 0

    fun addBeverage() {
        totalAmount += 100
    }

    fun addSnack(){
        totalAmount += 50
    }

    fun order(card: Card) = card.payment(card.number, totalAmount)
}

추상클래스인 Card의 구체적인 타입인 SCard가 결제기능을 가지고 있고 영수증을 생성한다.

SCard의 포인트 적립기능을 추가한 SCardPlus로 결제를 하더라도 기존의 코드가 오류 없이 작동한다.