반응형
1. 템플릿 메소드 패턴의 정의
메소드의 알고리즘의 공격을 정의한다. 알고리즘의 여러 단계중 일부는 서브클래스에서 구현할 수 있고, 이를 이용하면 알고리즘 구조는 그대로 이용하면서 특정단계만 재정의할 수있다.
상속받은 클래스에 기본 틀(추상클래스)이 정해져있고 세부적으로 구현하고싶은 메소드는 서브 클래스에서 구현하게하여 사용하는 방식
2. 예시
비슷한 기능을하는 커피와 티가 있다. 두개는 중복되는 부분이 너무 많은 클래스로서 템플릿 패턴을 적용하면 다음과 같다.
public class Coffee {
void prepareRecipe() {
boilWater();
brewCoffeeGrinds();
pourInCup();
addSugarAndMilk();
}
public void boilWater() {
System.out.println("물 끓이는 중");
}
public void brewCoffeeGrinds() {
System.out.println("필터를 통해서 커피를 우려내는 중");
}
public void pourInCup() {
System.out.println("컵에 따르는 중");
}
public void addSugarAndMilk() {
System.out.println("설탕과 우유를 추가하는 중");
}
}
public class Tea {
void prepareRecipe() {
boilWater();
steepTeaBag();
pourInCup();
addLemon();
}
public void boilWater() {
System.out.println("물 끓이는 중");
}
public void steepTeaBag() {
System.out.println("차를 우려내는 중");
}
public void pourInCup() {
System.out.println("컵에 따르는 중");
}
public void addLemon() {
System.out.println("레몬을 추가하는 중");
}
}
다음은 커피와 티가 상속받을 추상클래스이다.
abstract class CaffeineBeverage {
void final prepareRecipe(){
boilWater();
brew();
pourInCup();
addCondiments();
}
abstract void brew();
abstract void addCondiments();
void boilWater() {
System.out.println("물 끓이는 중");
}
void pourInCap() {
System.out.println("컵에 따르는 중");
}
}
상속받은 커피 클래스
public class Coffee extends CaffeineBeverage {
public void brew() {
System.out.println("필터로 커피 우려냄");
}
public void addCondiments() {
System.out.println("설탕과 커피를 추가함");
}
}
템플릿 메소드에서의 후크
정해진 알고리즘에서의 if문을 통해 과정을 실행시킬지 말지 선택하도록 하는부분을 후크라고 한다.
void prepareRecipe() {
boilWater();
brew();
pourInCup();
if (customerWantsCondiments()) {
addCondiments();
}
}
boolean customerWantsCondiments() {
return true;
}
사용자는 다음과 같이 customerWantsCondiments() 메소드를 재정의 하여 과정을 컨트롤 할 수 있다.
public class CoffeeWithHook extends CaffeineBeverageWithHook {
public void brew() {
// implements
}
public void addCondiments() {
// implements
}
public boolean customerWantsCondiments() {
String answer = getUserInput();
if (answer.toLowerCase().startsWith("y")) {
return true;
}
return false;
}
private String getUserInput() {
String answer = null;
System.out.println("커피에 우유와 설탕을 넣어 드릴까요?");
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
try {
answer = in.nextLine();
} catch (IOException ex) {
System.err.println("IO 오류");
}
if (answer == null) {
return "no";
}
return answer;
}
}
3. 템플릿 메소드 패턴의 예시
spring에서 디스패쳐 서블릿의 doService라는 함수가 템플릿 메소드로 구성되어있다. 아래와 같이 FrameworkServlet을 상속받아 doService메소드를 디스패쳐 서블릿에서 구체화하여 사용하고 있고 이는 템플릿 메소드패턴의 적절한 예시이다.
public class DispatcherServlet extends FrameworkServlet {
...
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
logRequest(request);
...중략...
}
...
}
반응형
'프로그래밍 > 시큐어코딩' 카테고리의 다른 글
[spring] webflux란? mono, flux란? (0) | 2020.10.22 |
---|---|
[Spring] @Async와 completablefuture란? (0) | 2020.07.27 |
[디자인 패턴] 빌더 패턴 (0) | 2020.07.15 |
[디자인 패턴] 퍼사드 패턴 (0) | 2020.07.14 |
[디자인 패턴] 어댑터 패턴 (0) | 2020.07.14 |