개발
Factory Method vs Template Method ― “누가 만들고, 누가 조립하나?”
스택큐힙리스트
2025. 7. 24. 11:21
반응형
큰 그림 먼저
두 패턴 모두 코드 중복을 줄이고 역할을 쪼개기 위한 도구지만, 초점이 다르다.
- Factory Method는 “어떤 객체를 만들지?”에 대한 생성 책임을 서브클래스에 넘긴다. API 사용자는 “어떤 구체 클래스인지” 모르는 채로 인스턴스를 받아 쓴다.
- Template Method는 “만들어진 객체가 어떻게 일할까?”에 대한 행위 흐름을 부모가 고정하고, 변동 단계만 자식에게 맡긴다.
둘을 조합하면 “공통 알고리즘 뼈대”는 Template Method로 잡고, 그 과정에서 필요한 “구체 객체”는 Factory Method로 생성하도록 설계할 수 있다. 예컨대 스프링 DispatcherServlet이 요청 흐름(Template) 안에서 View 객체를 뽑아낼 때 ViewResolver가 Factory Method 역할을 한다고 국내 인기 블로그들도 자주 소개한다.
코틀린 감각으로 비교해 보기
// 템플릿 메서드: 알고리즘 골격
abstract class ReportJob {
fun run() {
val reader = createReader() // ★ Factory Method 호출
val data = reader.read()
format(data)
send()
}
protected abstract fun createReader(): DataReader // Factory Method
protected abstract fun format(d: String)
protected open fun send() = println("메일 전송 완료")
}
// 팩토리 메서드: 객체 생성 책임
class CsvReportJob : ReportJob() {
override fun createReader() = CsvReader()
override fun format(d: String) = println("CSV 서식: $d")
}
class CsvReader : DataReader { override fun read() = "매출,10000" }
interface DataReader { fun read(): String }
fun main() { CsvReportJob().run() }
- run() 흐름은 Template Method — 절차를 바꿀 수 없다.
- createReader()는 Factory Method — 어떤 Reader를 만들지는 자식이 결정한다.
이렇게 분리하면 새로운 리더(JsonReader) 를 추가할 때 기존 알고리즘은 그대로 두고, 생성 책임만 새 하위 클래스가 맡는다.
언제 어떤 패턴이 유리할까?
- Factory Method
- 여러 제품군이 늘어날 때 “객체 생성 로직”을 갈아끼워야 한다.
- IoC 컨테이너·DI 프레임워크와 찰떡궁합.
- Template Method
- 동일한 작업 흐름이 반복되지만 중간 단계가 조금씩 다를 때.
- 프레임워크가 제어권을 갖고, 개발자는 훅만 구현하길 원할 때.
팁: 생성 로직이 복잡해지면 Factory Method를 Abstract Factory로 키우고, 흐름 제어가 런타임에 바뀌어야 하면 Template 대신 Strategy로 교체하라.
반응형