코드에는 크게 핵심기능과 부가기능으로 구분된다.
핵심 기능은 해당 객체가 제공하는 고유의 기능이다. 예를들어 주문 요청에 대해서는 주문이 핵심 기능이 된다.
부가 기능은 핵심 기능을 보조하기 위해 제공되는 기능이다. 예를 들어 주문 요청에 대해 로그를 남기는 로직, 데이터를 저장하기 위한 트랜잭션 기능이 있다. 부가 기능은 단독으로 사용되지 않고, 핵심 기능과 함께 사용된다.
핵심 기능 부분은 주로 변하고, 부가 기능 부분은 변하지 않는 부분이다. 이를 분리하여 설계하는것이 좋은 설계라고 할 수 있다.
템플릿 메서드 패턴은 이러한 문제를 해결할 수 있는 디자인 패턴이다.
추상 클래스를 이용한 템플릿 메서드 패턴 적용
// 템플릿 메서드 패턴을 적용해줄 추상 클래스
abstract class AbstractClass{
fun method(){
// 부가 기능
businessLogin()
// 부가 기능
}
abstract fun businessLogic()
}
// 추상클래스를 상속받아 구현될 클래스1
class BusinessLogicClass(): AbstracClass(){
override businessLogic(){
//비즈니스 로직 구현
}
}
// 추상클래스를 상속받아 구현될 클래스2
class BusinessLogicClass(): AbstracClass(){
override businessLogic(){
//비즈니스 로직 구현
}
}
class Controller(){
fun excute(){
val logic1: AbstractClass = BusinessLogicClass1()
val logic2: AbstractClass = BusinessLogicClass2()
logic1.method() //템플릿 메서드 패턴이 적용된 메서드
logic2.method()
// or
// 익명 내부 클래스 사용
// 각 구현된 익명 내부 클래스의 클래스이름은 생성된 순서대로 1, 2 로 네이밍된다.
val logic1 = object: AbstractClass(){
override fun businessLogic(){
//비즈니스 로직 구현
}
}
val logic2 = object: AbstractClass(){
override fun businessLogic(){
//비즈니스 로직 구현
}
}
logic1.method()
logic2.method()
}
}
- 중복된 부가 기능 코드가 없어짐
- 코드 수정이 부가기능이 사용된 횟수 n번 -> 1번으로 줄어든다.
단순히 소스코드 몇줄을 줄인것이 아닌 단일 책임 원칙(SRP)을 지킨 것이다. 변경 지점을 하나로 모아서 변경에 쉽게 대처할 수 있는 구조를 만든 것. -> 코드의 변경이 일어날 때 큰 이점을 볼 수 있다.
템플릿 메서드 패턴
부모 클래스를 통해 골격을 정의하고 그를 상속 받는 하위 클래스에서 변경이 되는 핵심 로직을 정의하는 것이다. 이렇게 되면 자식 클래스에서는 전체 구조를 변경하지 않고 특정 부분만 재정의가 가능하다. 상속과 오버라이딩을 통한 다형성으로 문제를 해결.
하지만 해당 패턴은 상속에서 오는 단점들을 그대로 안고간다. 자식 클래스는 부모 클래스를 강하게 의존하게 되므로, 부모 클래스에서 변경이 일어나면 모든 자식 클래스들은 영향을 받게되고, 극단적으로 부모 클래스에서 오류가 발생한다면 모든 자식 클래스 또한 오류가 발생하게 된다. 또한 부모 클래스의 기능을 전혀 사용하지 않더라고 부모 클래스를 알아야 한다 (ex 추상 메서드 추가 시 모든 자식 클래스에서도 추가해줘야함). 또 익명 클래스로 생성 시에도 같은 문제들이 발생할 수 있다.
* 템플릿 메서드 패턴의 단점을 제거할 수 있는 디자인 패턴 -> 전략 패턴(Strategy Pattern)
'Spring' 카테고리의 다른 글
[Spring] 빈 후처리기 - BeanPostProcessor (0) | 2021.11.08 |
---|---|
[Spring] 프록시 팩토리 (0) | 2021.11.08 |
[Spring] 프록시 패턴 (0) | 2021.11.05 |
[Spring] 전략 패턴 (0) | 2021.11.05 |
[Spring] 동시성 문제 + 해결 방법 (쓰레드 로컬) (0) | 2021.11.05 |