추상클래스는 abstract 키워드를 사용해 선언된 클래스이다. 일반적으로 추상메서드를 포함하는 클래스를 의미하지만, 포함하지 않더라도 abstract 키워드를 사용한 클래스라면 추상클래스이다. 해당 클래스는 new 를 통해 인스턴스화 시킬 수 없고 상속이 가능하다.
추상메서드란 구현 코드가 없이, 선언부만 있는 메서드를 의미하고 abstract 키워드를 붙인 메서드이다.
public abstract void turnOn();
위와 같은 메서드 형식이다.
Template Pattern 은 Template Method를 활용한 디자인 패턴이다.
그렇다면 Template Method 는 무엇일까?
템플릿 패턴은 추상메서드 혹은 구현된 일반적인 메서드를 활용해 전체적인 흐름을 정해놓은 메서드로, final 키워드를 활용해 하위클래스에서 재정의 할 수 없게 해야한다. 조금 더 쉽게 이해하기 위해 코드를 살펴보자
public abstract class Car {
public void turnOn(){
System.out.println("시동을 켠다");
};
public abstract void drive();
public void turnOff(){
System.out.println("시동을 끈다.");
}
// 템플릿 메서드
public final void driving(){
turnOn();
drive();
turnOff();
}
}
다음 코드에서 마지막 메서드를 템플릿 메서드라고 정의내릴 수 있는데, driving() 메서들 통해 로직의 flow 가 설정되었다. 내부의 drive() 메서드의 구현은 하위 클래스에 delegate 하였고 turnOn() 과 turnOff()는 구현되어있지만 overriding 도 가능하다. 하지만 로직의 흐름(시나리오) 는 변경이 불가능하고 오직 turnOn() -> drive() -> turnOff() 의 흐름으로 실행된다.
여기서, 흐름을 미리 설정해둔다고 하였는데 프레임워크의 특성과 유사한 점을 생각해보면 템플릿 패턴은 프레임워크를 설계할때 많이 사용되는 패턴임을 짐작 할 수 있다.
우선, 위에 작성한 코드를 이용하여 템플릿 패턴을 활용하는 간단한 프로그램을 작성해 보자.
Abstracr Class 인 Car 클래스를 상속받은 SprotsCar 와 EcoCar class를 만들어 drive() 메서드를 구현했다. 그렇다면 해당 클래스를 사용해보도록 하자.
결과는 다음과 같다.
템플릿 패턴에는 HookMethod 라는 개념도 존재한다. 쉽게 설명하자면 하위클래스에서 흐름의 중간중간에 필요하다면 끼어들수(?)있게 하기 위한 개념인데 코드를 통해 살펴보록 하자.
위를 보면, drive() 다음에 수행될 afterDirveStart()와 turnOff() 다음에 수행될 afterTrunOff()가 끼어들어갔다. 위 코드는 이 클래스를 상속하는 클래스에서 구현하면 흐름중 원하는 곳에서 로직을 수행하게 된다. 물론 구현하지 않는다면 그냥 넘어가게 될 것이다.
예를들어 사용하자면 다음과 같다.
위와같이, 하위클래스에서 필요에따라 흐름의 중간중간 필요한 로직을 수행할 수 있는 역할을 하는 것을 HookMethod 라고 생각하면 되겠다.
템플릿 패턴을 사용하면 정해진 흐름을 이용할 수 있다. 앞서서 템플릿패턴은 프레임워크를 설계할때 많이 사용된다고 하였는데 그렇다면 Spring 프레임워크에서 템플릿 패턴을 찾아보도록 하자.
다음은, 스프링 MVC에서 사용하는 DispatcherServlet의 상위클래스 FrameworkServlet 의 processRequest()메서드이다. 잘 보면 이 메서드는 final 키워드가 붙어있고, try 위의 작업을 수행한 후 doService()를 하고 finally 를 실행하는 로직의 flow 를 가지고 있다. 그리고 doService() 메서드의 경우
abstract 메서드로 구현을 하위클래스에 delegate 하고 있음을 알 수 있다.
즉 doSerivce()에 대한 구현부는 FrameWordkServlet을 상속한 DispatcherServlet 이 구현하고 있다.
여하튼, 스프링에서도 이렇게 템플릿패턴이 적용되어있음을 확인해 볼 수 있었다.