템플릿 메서드 패턴 (Template method pattern)은 행동 관점의 디자인 패턴 (Behavioral design pattern)의 일종으로 실행 과정 전반이 동일한 타입의 세부 메서드들을 각 타입에서 구현하여 필요에 따라 유사하지만 다른 수행 로직을 가진 타입을 만드는 방식을 이릅니다.
선택 모드에 따라 다른 지도 API를 사용하여 지도를 로드하는 경우를 살펴보겠습니다. 사용할 지도 API는 네이버, 카카오로 다르지만 지도를 불러올(초기화) 때 아래의 순서는 유지된다고 가정합니다.
지도를 초기화하는 메서드를 포함해 위에서 가정한 1, 2, 3에 맞는 기능을 외부에 제공할 인터페이스를 아래와 같이 프로토콜을 통해 정의합니다. 동시에 프로토콜 기본 구현 (Protocol default implementation)을 통해 구현할 기능이 의도한 순서대로 실행해주는 메서드를 구현합니다.
protocol MapView {
func connectMapServer()
func showMapOnScreen()
func moveToCurrentLocation()
func initMap()
}
extension MapView {
func initMap() {
connectMapServer()
showMapOnScreen()
moveToCurrentLocation()
}
}
정의한 프로토콜을 준수하며 각 지도 API를 통해 지도를 불러올 타입을 정의합니다.
struct NaverMapView: MapView {
func connectMapServer() {
print("네이버 지도 서버에 연결")
}
func showMapOnScreen() {
print("네이버 지도 보여주기")
}
func moveToCurrentLocation() {
print("네이버 지도에서 현재 좌표로 이동")
}
}
struct KaKaoMapView: MapView {
func connectMapServer() {
print("카카오 지도 서버에 연결")
}
func showMapOnScreen() {
print("카카오 지도 보여주기")
}
func moveToCurrentLocation() {
print("카카오 지도에서 현재 좌표로 이동")
}
}
각 타입은 MapView
프로토콜이 기본 구현한 initMap()
메서드를 이미 가지고 있으므로 해당 메서드를 통해 지도를 불러오면 됩니다. 다른 지도 API를 통해 지도를 초기화한다고 하여도 이미 정의해둔 타입과 동일한 방식으로 MapView
프로토콜을 준수하는 타입을 정의하여 사용하면 됩니다.