Template Method Pattern

Muzi·2023년 4월 20일
0

디자인 패턴

목록 보기
3/14

Intro

  • 상위 클래스에서 처리 흐름을 정하고 하위 클래스에서 구체적인 내용을 결정하는 패턴
  • 상위 클래스에 템플릿이 되는 메서드가 있고, 그 메소드의 정의에 추상 메서드가 사용됨
  • 실제 구현은 하위 클래스에서 이루어진다. 때문에 하위 클래스가 정의 되어야 한다
  • 템플릿 메서드 패턴에는 후크 라는 것을 사용하는데, 후크는 추상클레스에서 간단한 기본적인 내용이 구현되어 있거나, 아무 코드도 구현 되지 않는 코드를 말한다. 그래서 추상 클레스를 상속 받은 하위 클래스는 여기에 추가적인 코드를 구현한다


예시

예시가 재밌어서 해당 블로그를 참고했습니다

진라면, 삼양, 신라면, 너구리 4가지 라면을 끓인다 가정하자.
우리는 어떤 종류의 라면을 끓이는지 상관없이, 국물라면이라면 아래 순서대로 조리하는 것이 일반적일 것 이다.

가스 불 켜기 -> 냄비에 물 받고 끓이기 -> 라면을 준비한다 -> 스프와 면 넣기 -> 가스 불을 끈다

여기서 '라면을 준비한다' 단계는 어떤 종류의 라면인지에 따라 구현이 달라질 것이다

템플릿 메소드 패턴이 없다면

아래의 코드처럼 실질적으로 다르게 구현한 부분은 '라면을 준비한다' 하나 밖에 없음에도 불구하고, 나머지 4가지 작업에 대한 코드가 중복되는 문제가 생긴다

// JinRamyun.java
public class JinRamyun {
    public void cook() {
        System.out.println("가스불을 켠다.");
        System.out.println("냄비에 물을 받고 끓인다.");
        System.out.println("진라면을 준비한다."); // 이 부분만 다름
        System.out.println("스프와 면을 넣는다.");
        System.out.println("가스불을 끈다.");
    }
}

// SamyangRamyun.java
public class SamyangRamyun {
    public void cook() {
        System.out.println("가스불을 켠다.");
        System.out.println("냄비에 물을 받고 끓인다.");
        System.out.println("삼양라면을 준비한다."); // 이 부분만 다름
        System.out.println("스프와 면을 넣는다.");
        System.out.println("가스불을 끈다.");
    }
}

// NeoguriRamyun.java
public class NeoguriRamyun {
    public void cook() {
        System.out.println("가스불을 켠다.");
        System.out.println("냄비에 물을 받고 끓인다.");
        System.out.println("너구리 라면을 준비한다."); // 이 부분만 다름
        System.out.println("스프와 면을 넣는다.");
        System.out.println("가스불을 끈다.");
    }
}

다시 정리하자면,,,

템플릿 메소드 패턴이란 특정 작업을 처리하는 일부분을 서브 클래스로 캡슐화하여 전체적인 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내용을 바꾸는 패턴이다.
즉, 두개 이상의 프로그램이 기본적으로 동일한 골격 안에서 동작할때 기본 골격에 해당하는 알고리즘은 일괄적으로 관리하고 각 프로그램마다 달라지는 부분들에 대해서는 따로 만들고 싶을때 템플릿 메소드 패턴을 사용한다


장단점

장점

아래의 장점들 덕분에 좀더 코드를 객체지향적으로 구성할 수 있다.

  1. 중복 코드를 줄일 수 있다.(중복은 버그의 잠재적인 원인)
  2. 하위 클래스의 역할을 줄여 핵심 로직의 관리가 용이하다
  3. 알고리즘의 구조를 상위 클래스에서 정의하기 때문에, 구조를 변경하려면 상위 클래스만 수정하면 되기때문에 유지보수에 용이하다
  4. 관심을 가져야 할 코드의 범위가 매우 줄어든다. 상위의 흐름이 문제라면 상위 클래스만 보면 되고, 하위의 구현체에서 문제가 있다면 해당 구현체만 확인하면 된다

단점

  1. 클래스간의 관계와 코드가 꼬여버릴 염려가 있다
    • 템플릿 메소드 패턴에서는 상위 클래스가 하위 클래스의 구현에 대해 강력한 제어력을 가지는데, 이는 하위 클래스에서 상위 클래스의 변경에 대한 영향을 받을 가능성이 크다는 뜻
    • 상위 클래스에서 하위 클래스에게 구현을 요구하는 메소드가 너무 많거나 복잡할 경우, 하위 클래스에서는 그 구현을 어렵게 할 수 있다.

사용 예제

해당 예제는 선생님이라는 상위 클래스를 추상 클래스로 작성한 후 국어, 수학, 영어 선생님의 teach()를 재정의해서 템플릿 메소드를 구현한다

//추상 클래스 선생님
abstract class Teacher{
	
    public void start_class() {
        inside();
        attendance();
        teach();
        outside();
    }
	
    // 공통 메서드
    public void inside() {
        System.out.println("선생님이 강의실로 들어옵니다.");
    }
    
    public void attendance() {
        System.out.println("선생님이 출석을 부릅니다.");
    }
    
    public void outside() {
        System.out.println("선생님이 강의실을 나갑니다.");
    }
    
    // 추상 메서드
    abstract void teach();
}
 
// 국어 선생님
class Korean_Teacher extends Teacher{
    
    @Override
    public void teach() {
        System.out.println("선생님이 국어를 수업합니다.");
    }
}
 
//수학 선생님
class Math_Teacher extends Teacher{

    @Override
    public void teach() {
        System.out.println("선생님이 수학을 수업합니다.");
    }
}

//영어 선생님
class English_Teacher extends Teacher{

    @Override
    public void teach() {
        System.out.println("선생님이 영어를 수업합니다.");
    }
}

Reference

https://hudi.blog/template-method-pattern/
https://coding-factory.tistory.com/712
https://velog.io/@malleus35/Java%EC%96%B8%EC%96%B4%EB%A1%9C-%EB%B0%B0%EC%9A%B0%EB%8A%94-%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-%EC%9E%85%EB%AC%B8-%EC%A0%95%EB%A6%AC-3.-Template-Method-Pattern

profile
좋아하는걸 열심히

0개의 댓글