디자인 패턴
템플릿 메소드 패턴 (Template Method Pattern)
dev-sh
2020. 12. 7. 22:10
템플릿 메소드는 템플릿을 제공하는 메소드, 하위 클래스에게 구현을 강제하는 추상 메소드, 하위 클래스가 선택적으로 오버라이딩할 수 있는 Hook 메소드를 두는 패턴을 템플릿 메소드 패턴이라 한다.
이해가 되지 않는다면, 코드를 보는 것이 좋다.
억지스럽게 코드를 한번 작성해보겠다. 너무 불편해하지 않았으면 좋겠다.
public class Bmw {
public void driveOnRoad() {
System.out.println("자동차 시동 부릉");
System.out.println("수동 기어로 시작");
System.out.println("정지");
System.out.println("자동차 시동 끄기");
}
}
public class Audi {
public void driveOnRoad() {
System.out.println("자동차 시동 부릉");
System.out.println("자동 기어로 시작");
System.out.println("정지");
System.out.println("자동차 시동 끄기");
}
}
위와 같은 코드가 있다고 하자. 객체 지향의 특징을 조금이나마 이해하고 있다면, 위에서 반복적하는 코드에 대한 리팩토링 의지가 불타오를 것인다. 따라서 이를 템플릿 메소드 패턴을 적용하여 개선해보자.
package 템플릿메소드패턴;
public abstract class Car {
public void driveOnRoad() {
System.out.println("자동차 시동 부릉");
drive();
stop();
System.out.println("자동차 시동 끄기");
}
abstract drive();
void stop() {
System.out.println("정지");
}
}
package 템플릿메소드패턴;
public class Bmw extends Car {
@Override
void drive() {
System.out.println("자동 주행");
}
@Override
void stop() {
System.out.println("Bmw 정지");
}
}
package 템플릿메소드패턴;
public class Audi extends Car {
@Override
void drive() {
System.out.println("수동 주행");
}
@Override
void stop() {
System.out.println("Audi 정지");
}
}
코드만 봐서 이해가 안될 것인다. 하나 하나 짚어서 설명해보겠다.
템플릿 메소드 패턴 구성 요소 | 상위 클래스 Car | 하위 클래스 (Bmw, Audi) |
템플릿 메소드는 공통 로직을 수행하는 부분, 공통 로직 안에서 하위 클래스에서 오버라이딩한 추상 메소드/훅 메소드를 호출 | driveOnRoad() | |
템플릿 메소드에서 호출하는 추상 메소드, 하위 클래스가 반드시 오버라이딩하도록 만든다. | drive() | 오버라이딩 필수 |
템플릿 메소드에서 호출하는 훅 메소드를 하위 클래스에서 선택적으로 오버라이딩합니다. | stop() | 오버라이딩 선택 |
"상위 클래스의 견본 메서드에서 하위 클래스가 오버라이딩한 메소드를 호출하는 패턴"
템플릿 메소드 패턴이 의존 역전 법칙(DIP)을 활용하고 있음을 알 수 있다. 이 패턴을 통해서 중복되는 공통 로직을 리팩토링하고, 개별로 다르게 진행되는 로직은 추상 메소드와 훅 메소드를 사용하여 강제로 오버라이딩하거나 선택적으로 오버라이딩할 수 있습니다.
guy-who-writes-sourcecode.tistory.com/30