inblog logo
|
parangdajavous
    Design pattern

    Design pattern 5. Template Method Pattern

    김미숙's avatar
    김미숙
    Jul 22, 2025
    Design pattern 5. Template Method Pattern
    Contents
    ✅ 1. 템플릿 메서드 패턴이란?실습
    💡
    가장 많이 쓰는 기술
    핵심은 공통적인 기능을 추상화시키는 것

    ✅ 1. 템플릿 메서드 패턴이란?

    • 객체지향 디자인 패턴 중 하나로, 알고리즘의 전체 흐름은 상위 클래스에 정의하고, 세부 구현은 하위 클래스에 위임하는 패턴
    • 상위 클래스(추상 클래스)에 알고리즘의 공통적인 뼈대(템플릿)를 정의하고, 일부 단계는 하위 클래스가 구현하도록 만드는 패턴
     

    🔧 구조

    🔼 상위 클래스 (추상 클래스)
    public abstract class LoginTemplate { // 템플릿 메서드 (고정된 로직 흐름) public final void loginProcess() { authenticate(); // 1단계 getProfile(); // 2단계 showMainPage(); // 3단계 } protected abstract void authenticate(); protected abstract Profile getProfile(); protected void showMainPage() { System.out.println("메인 페이지로 이동합니다."); } }
    • loginProcess()는 변하지 않는 알고리즘의 전체 흐름을 정의
    • authenticate()와 getProfile()은 하위 클래스가 구체적으로 구현
    🔽 하위 클래스 (구체 구현)
    public class GoogleLogin extends LoginTemplate { @Override protected void authenticate() { System.out.println("구글 로그인 인증 중..."); } @Override protected Profile getProfile() { System.out.println("구글 프로필 가져오기 완료"); return new GoogleProfile(1, "cos"); } }
    public class KakaoLogin extends LoginTemplate { @Override protected void authenticate() { System.out.println("카카오 로그인 인증 중..."); } @Override protected Profile getProfile() { System.out.println("카카오 프로필 가져오기 완료"); return new KakaoProfile(2, "ssar"); } }
    ✅ 사용 예시
    public class App { public static void main(String[] args) { LoginTemplate login = new GoogleLogin(); login.loginProcess(); // 고정된 흐름대로 실행 } }
    출력:
    구글 로그인 인증 중... 구글 프로필 가져오기 완료 메인 페이지로 이동합니다.
     

    ✅ 장점

    장점
    설명
    ✅ 코드 재사용
    공통 로직은 상위 클래스에 작성, 반복 줄임
    ✅ 변경에 유연
    세부 단계만 하위 클래스에서 오버라이드 가능
    ✅ 유지보수 용이
    알고리즘 구조가 한 곳에 정의되어 명확함
     

    ❗️ 주의사항

    • 상속 기반이라 하위 클래스가 하나만 상속 가능
    • 너무 많은 추상 메서드를 강요하면 하위 클래스가 복잡해짐
     

    💡 한줄 요약

    템플릿 메서드는 전체 흐름은 상위 클래스에서 고정, 세부 로직만 하위 클래스에서 바꾸는 패턴
     

    실습

    HTMLTeacher
    package ex05.teacher; public class HTMLTeacher { public void 수업시작() { 입장하기(); 출석부르기(); 강의하기(); 퇴장하기(); } private void 입장하기() { System.out.println("입장하기"); } private void 출석부르기() { System.out.println("출석부르기"); } private void 강의하기() { System.out.println("HTML 강의하기"); } private void 퇴장하기() { System.out.println("퇴장하기"); } }
    JavaTeacher
    package ex05.teacher; public class JavaTeacher { // 이 메서드만 노출되므로 개념상 interface - 강제성이 부여되어있음 public void 수업시작() { 입장하기(); 출석부르기(); 강의하기(); 퇴장하기(); } // public일 경우 자유도가 높아서 순서를 보장하기 힘들다 private void 입장하기() { System.out.println("입장하기"); } private void 출석부르기() { System.out.println("출석부르기"); } private void 강의하기() { System.out.println("Java 강의하기"); } private void 퇴장하기() { System.out.println("퇴장하기"); } }
    PythonTeacher
    package ex05.teacher; public class PythonTeacher { public void 수업시작() { 입장하기(); 출석부르기(); 강의하기(); 퇴장하기(); } private void 입장하기() { System.out.println("입장하기"); } private void 출석부르기() { System.out.println("출석부르기"); } private void 강의하기() { System.out.println("Python 강의하기"); } private void 퇴장하기() { System.out.println("퇴장하기"); } }
    App
    package ex05; import ex05.teacher.HTMLTeacher; import ex05.teacher.JavaTeacher; import ex05.teacher.PythonTeacher; public class App { public static void main(String[] args) { JavaTeacher jt = new JavaTeacher(); jt.수업시작(); PythonTeacher pt = new PythonTeacher(); pt.수업시작(); HTMLTeacher htt = new HTMLTeacher(); htt.수업시작(); } }
    notion image
    → 공통적인 것들 중 강의하기는 구현체가 Teacher 마다 다 다르므로 추상메서드로 만들어야한다

    추상화

    • 공통적인 것(Teacher)을 추상화 시킨다
    Teacher
    package ex05.teacher; public abstract class Teacher { public void 수업시작() { 입장하기(); 출석부르기(); 강의하기(); 퇴장하기(); } protected void 입장하기() { System.out.println("입장하기"); } protected void 출석부르기() { System.out.println("출석부르기"); } // 추상메서드 protected abstract void 강의하기(); protected void 퇴장하기() { System.out.println("퇴장하기"); } }
    → 강의하기는 Teacher마다 다르므로 추상 메서드로 구현
    → 수업시작을 제외하고는 노출되면 안 되므로 나머지 메서드는 protected로 구현 (캡슐화)
    HTMLTeacher
    package ex05.teacher; public class HTMLTeacher extends Teacher { @Override public void 강의하기() { System.out.println("HTML 강의하기"); } }
    JavaTeacher
    package ex05.teacher; public class JavaTeacher extends Teacher { @Override public void 강의하기() { System.out.println("Java 강의하기"); } }
    PythonTeacher
    package ex05.teacher; public class PythonTeacher extends Teacher { @Override public void 강의하기() { System.out.println("Python 강의하기"); } }
    App
    package ex05; import ex05.teacher.HTMLTeacher; import ex05.teacher.JavaTeacher; import ex05.teacher.PythonTeacher; import ex05.teacher.Teacher; public class App { public static void main(String[] args) { Teacher jt = new JavaTeacher(); jt.수업시작(); Teacher pt = new PythonTeacher(); pt.수업시작(); Teacher htt = new HTMLTeacher(); htt.수업시작(); } }

    인터페이스 만들기

    • 인터페이스를 정의하는 목적: 노출시키고 싶은 것만 노출하기 위함
    TeacherAble
    package ex05.teacher; /* 주석으로 누가 만들었는지, 어디서 구현하면 되는지 기재 */ public interface TeacherAble { // 이 메서드만 노출시킨다 void 수업시작(); }
    Teacher
    package ex05.teacher; public abstract class Teacher implements TeacherAble { public void 수업시작() { 입장하기(); 출석부르기(); 강의하기(); 퇴장하기(); } protected void 입장하기() { System.out.println("입장하기"); } protected void 출석부르기() { System.out.println("출석부르기"); } // 추상메서드 protected abstract void 강의하기(); protected void 퇴장하기() { System.out.println("퇴장하기"); } }
    notion image
    Share article
    Contents
    ✅ 1. 템플릿 메서드 패턴이란?실습

    parangdajavous

    RSS·Powered by Inblog