노트코드
노트코드
노트코드

블로그 메뉴

  • 홈
  • 이력서
  • 이전 블로그
  • 글쓰기
  • 관리자페이지
  • 분류 전체보기 (57)
    • 코틀린 (2)
      • 실무 프로젝트로 배우는 Kotlin & Sprin.. (2)
    • JAVA (1)
      • 디자인패턴 (1)
      • 객체지향 5대원칙 (0)
    • SPRING (32)
      • JPA (11)
      • 스프링시큐리티 (1)
      • 스프링 (8)
      • QueryDsl (1)
      • 스프링배치 (11)
    • AZURE (0)
    • ETC (10)
      • MAVEN (0)
      • GIT (0)
      • ReMind (3)
      • Exception (1)
      • CS (6)
    • 책 (8)
      • 이것이 자바다 (8)

최근 글

최근 댓글

태그

  • 스프링
  • JPA
전체 방문자
오늘
어제
hELLO · Designed By 정상우.
노트코드

노트코드

SPRING/스프링

[스프링 핵심 원리-고급] 템플릿 메서드 패턴

2022. 1. 25. 01:05
변하는 것과 변하지 않는 것을 분리한다



좋은 설계는 변하는 것과 변하지 않는 것을 분리하는것

템플릿 메서드 패턴은 이런 문제를 해결하는 디자인 패턴이다.

 

템플릿 메서드 패턴은 이름 그대로 템플릿을 사용하는 방식,

템플릿은 기준이 되는 거대한 틀이다. 템플릿이라는 틀에 변하지 않는 부분은 몰아둔다.

그리고 일부 변하는 부분을 별도로 호출해서 해결한다.

 

템플릿 메서드 디자인 패턴의 목적

- 작업에서 알고리즘의 골격을 정의하고 일부 단계를 하위 클래스로 연기한다.

템플릿 메서드를 사용하면 하위 클래스가 알고리즘의 구조를 변경하지 않고도 알고리즘의 특정 단계를 정의할 수 있다.

 

예제 코드 생성

@Slf4j
public class TemplateMethodTest {

    @Test
    void templateMethodV0(){
        logic1();
        logic2();

    }

    private void logic1(){
        long startTime = System.currentTimeMillis();
        //비지니스 로직 실행
        log.info("비지니스 로직1 실행");
        //비지니스 로직 종료
        long entTime = System.currentTimeMillis();
        long resultTime = entTime - startTime;
        log.info("resultTime ={}", resultTime);
    }

    private void logic2(){
        long startTime = System.currentTimeMillis();
        //비지니스 로직 실행
        log.info("비지니스 로직2 실행");
        //비지니스 로직 종료
        long entTime = System.currentTimeMillis();
        long resultTime = entTime - startTime;
        log.info("resultTime ={}", resultTime);
    }
    
//00:41:03.303 [Test worker] INFO hello.advanced.trace.template.TemplateMethodTest - 비지니스 로직1 실행
//00:41:03.308 [Test worker] INFO hello.advanced.trace.template.TemplateMethodTest - resultTime =7
//00:41:03.310 [Test worker] INFO hello.advanced.trace.template.TemplateMethodTest - 비지니스 로직2 실행
//00:41:03.311 [Test worker] INFO hello.advanced.trace.template.TemplateMethodTest - resultTime =1
}

추상 클래스를 만들고, 변하는 부분은 추상메소드로 만들어, 상속받아서 사용하는 곳에서 각 자식이
자신에게 필요한 메소드를 구현하여 사용한다.

@Slf4j
public abstract class AbstractTemplate {

    public void execute(){
        long startTime = System.currentTimeMillis();
        //비지니스 로직 실행
        call();
        //비지니스 로직 종료
        long entTime = System.currentTimeMillis();
        long resultTime = entTime - startTime;
        log.info("resultTime ={}", resultTime);
    }

    protected abstract void call();
}

상속받은 클래스를 생성

@Slf4j
public class SubClassLogic1 extends AbstractTemplate {
    @Override
    protected void call() {
        log.info("비즈니스 로직1 실행");
    }
}

@Slf4j
public class SubClassLogic2 extends AbstractTemplate {
    @Override
    protected void call() {
        log.info("비지니스 로직2");
    }
}

실행

@Slf4j
public class TemplateMethodTest {
    @Test
    void templateMethodV1() {
        AbstractTemplate template1 = new SubClassLogic1();
        template1.execute();

        AbstractTemplate template2 = new SubClassLogic2();
        template2.execute();

    }
    
//00:56:43.063 [Test worker] INFO hello.advanced.trace.template.code.SubClassLogic1 - 비즈니스 로직1 실행
//00:56:43.067 [Test worker] INFO hello.advanced.trace.template.code.AbstractTemplate - resultTime =6
//00:56:43.068 [Test worker] INFO hello.advanced.trace.template.code.SubClassLogic2 - 비지니스 로직2
//00:56:43.068 [Test worker] INFO hello.advanced.trace.template.code.AbstractTemplate - resultTime =0
}

공통되는 부분을 하나로 만들었기때문에, 공통 되는 부분의 코드가 변경될시,

한번만 수정해줘도 됨(기존 코드라면 logic1, logic2를 각각 수정해줘야함)

 

익명 내부클래스를 활용한 클래스파일 생성 줄이기

@Slf4j
public class TemplateMethodTest {
    @Test
    void templateMethodV2() {
        AbstractTemplate template1 = new AbstractTemplate() {
            @Override
            protected void call() {
                log.info("비지니스 로직1 실행");
            }
        };
        template1.execute();

        AbstractTemplate template2 = new AbstractTemplate() {
            @Override
            protected void call() {
                log.info("비지니스 로직2 실행");
            }
        };
        template2.execute();

    }
}

 

 

단점

템플릿 메소드 패턴은 상속을 사용하여, 상속에서 오는 단점들을 그대로 가지고 있음

1. 자식 클래스가 부모 클래스와 컴파일 시점에 강하게 결합되는 문제가 있다.

2. 자식 클래스 입장에서는 부모 클래스의 기능을 전혀 사용하지 않는데, 부모 클래스를 알아야 한다.

3. 별도의 클래스나 익명 내부 클래스를 만들어야 하는 부분도 복잡하다.

 

'SPRING > 스프링' 카테고리의 다른 글

[스프링 핵심 원리-고급] 템플릿 콜백 패턴  (0) 2022.01.27
[스프링 핵심 원리 -고급] 전략패턴  (0) 2022.01.27
[스프링 핵심 원리-고급] 쓰레드 로컬 주의사항  (0) 2022.01.22
[스프링 핵심 원리-고급] ThreadLocal  (0) 2022.01.21
[스프링 핵심 원리-고급]필드 동기화 -동시성 문제  (0) 2022.01.21
    'SPRING/스프링' 카테고리의 다른 글
    • [스프링 핵심 원리-고급] 템플릿 콜백 패턴
    • [스프링 핵심 원리 -고급] 전략패턴
    • [스프링 핵심 원리-고급] 쓰레드 로컬 주의사항
    • [스프링 핵심 원리-고급] ThreadLocal
    노트코드
    노트코드
    노션 블로그에서 티스토리로 이전공사중

    티스토리툴바