가장 많이 쓰는 기술
핵심은 공통적인 기능을 추상화시키는 것
✅ 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.수업시작();
}
}

→ 공통적인 것들 중 강의하기는 구현체가 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("퇴장하기");
}
}

Share article