-핵심 기능 : 해당 객체가 제공하는 고유 기능
-부가 기능 : 핵심 기능을 보조하기 위해 제공되는 기능 (예. 로그 추적 로직, 트랜잭션 기능 등)
V3 코드를 유심히 살펴보면 다음과 같이 동일한 패턴이 있다
TraceStatus status = null;
try {
status = trace.begin("message");
// 핵심 기능 호출
trace.end(status);
} catch(Exception e) {
trace.exception(status, e);
throw e;
}
Controller, Service, Repository 모두가 로그 추적기를 사용하는 구조는 모두 동일하다. 중간에 핵심 기능을 사용하는 코드만 다를 뿐이다.
부가 기능과 관련된 코드가 중복되니 중복 코드를 별도의 메서드로 뽑아서 사용하면 될 것 같다.
“변하는 것과 변하지 않는 것을 분리”
좋은 설계는 변하는 것과 변하지 않는 것을 분리하는 것이다.
여기서 핵심 기능 부분은 변하고, 로그 추적기를 사용하는 부분은 변하지 않는 부분이다.
이 둘을 분리해서 모듈화 하도록 한다.
상속을 통한 다형성
아래 예제를 살펴볼 때 logic1() 과 logic2() 가 비즈니스 로직 부분 제외한 나머지 부분이 중복된 형태를 보인다
@Test
void templateMethodV0() {
logic1();
logic2();
}
private void logic1() {
long startTime = System.currentTimeMillis();
// 비즈니스 로직 실행
log.info("비즈니스 로직1 실행");
// 비즈니스 로직 종료
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime = {}", resultTime);
}
private void logic2() {
long startTime = System.currentTimeMillis();
// 비즈니스 로직 실행
log.info("비즈니스 로직2 실행");
// 비즈니스 로직 종료
long endTime = System.currentTimeMillis();
long resultTime = endTime - startTime;
log.info("resultTime = {}", resultTime);
}