Backend

TemplateMethod Pattern

뭉크테크 2026. 8. 3. 19:40

정의

  • 부모 클래스에서 구현해야할 객체의 단계를 전체적으로 정의한다음, 자식 클래스마다 달라지는 단계에 대해서만 부모 클래스단에서 추상 메서드로 정의하여 자식클래스가 해당 메서드를 오버라이드할 수 있게 하는 패턴

목적

  • 비슷한 개념을 가진 객체들의 중복되는 코드는 부모클래스에서 정의하기에 코드 길이가 줄어들며, 관리하기가 용이하다.
  • 해당 패턴을 사용하지 않을 경우
class Coffee {
    fun make(): List<String> {
        val result = mutableListOf<String>()

        result.add("물을 끓입니다.")
        result.add("커피 원두를 내립니다.")
        result.add("컵에 따릅니다.")
        result.add("설탕과 우유를 넣습니다.")

        return result
    }
}

class Tea {
    fun make(): List<String> {
        val result = mutableListOf<String>()

        result.add("물을 끓입니다.")
        result.add("찻잎을 우립니다.")
        result.add("컵에 따릅니다.")
        result.add("레몬을 넣습니다.")

        return result
    }
}
  • 두 클래스 모두 서로 비슷한 개념을 가진 객체들이며, 물을 끓입니다와 컵에 따릅니다 라는 과정이 겹치는 문구가 나타난다.

 

코드

abstract class Beverage {

    fun make(): List<String> {
        val result = mutableListOf<String>()

        result.add(boilWater())
        result.add(brew())
        result.add(pourInCup())
        result.add(addCondiments())

        return result
    }

    private fun boilWater(): String {
        return "물을 끓입니다."
    }

    protected abstract fun brew(): String

    private fun pourInCup(): String {
        return "컵에 따릅니다."
    }

    protected abstract fun addCondiments(): String
}
  • Beverage 라는 부모클래스를 별도로 만들어서 겹치는 과정은 부모클래스단에서 정의하며,
  • protected abstract fun brew(): String
    protected abstract fun addCondiments(): String
    • 자식 클래스마다 달라질만한 부분들은 별도로 abstract로 선언하여 추상 메서드로서 선언한다.
class Coffee : Beverage() {

    override fun brew(): String {
        return "커피 원두를 내립니다."
    }

    override fun addCondiments(): String {
        return "설탕과 우유를 넣습니다."
    }
}

class Tea : Beverage() {

    override fun brew(): String {
        return "찻잎을 우립니다."
    }

    override fun addCondiments(): String {
        return "레몬을 넣습니다."
    }
}
  • 추상 메서드를 자식클래스에서 위와같이 구현한다.
  • 이러면 자식클래스들이 지켜야할 부모클래스의 전체적인 단계를 따르면서도 공통 부분들은 굳이 따로 자식단에서 구현하지 않아도 되며, brew()와 addCondiments() 함수 또한 부모가 정한 함수 이름·매개변수·반환 타입을 지키기에 이부분에 있어서도 나름의 통일성을 가진다.