이번 포스팅에서는 디자인 패턴 중 하나인 템플릿 메서드 패턴에 관해 알아본다.
우선, 템플릿 메서드 패턴을 알아보기 위해 App, Teacher 클래스를 생성한다.
Teacher
public class Teacher {
private void 입장하기(){
System.out.println("입장하기");
}
private void 출석부르기(){
System.out.println("출석부르기");
}
private void 퇴장하기(){
System.out.println("퇴장하기");
}
public void 수업시작(){
입장하기();
출석부르기();
퇴장하기();
}
}
App.java
public class App {
public static void main(String[] args) {
Teacher teacher = new JavaTeacher();
teacher.수업시작();
}
}
Teacher는 수업시작시
(수업시작 - 내부가 어떻게 구성되어있는지 모르지만 수업시작()만 호출하면 되므로 캡슐화라고 볼 수 있다.)
입장하기 -> 출석부르기 -> 퇴장하기의 역할을 한다.
이때, JavaTeacher와 PythonTeacher를 추가해보자.
JavaTeacher
public class JavaTeacher {
private void 입장하기(){
System.out.println("입장하기");
}
private void 출석부르기(){
System.out.println("출석부르기");
}
private void 강의하기(){
System.out.println("Java 강의하기");
}
private void 퇴장하기(){
System.out.println("퇴장하기");
}
public void 수업시작(){
입장하기();
출석부르기();
강의하기();
퇴장하기();
}
}
PythonTeacher
public class PythonTeacher {
private void 입장하기(){
System.out.println("입장하기");
}
private void 출석부르기(){
System.out.println("출석부르기");
}
private void 강의하기(){
System.out.println("Python 강의하기");
}
private void 퇴장하기(){
System.out.println("퇴장하기");
}
public void 수업시작(){
입장하기();
출석부르기();
강의하기();
퇴장하기();
}
}
App
public class App {
public static void main(String[] args) {
JavaTeacher javaTeacher = new JavaTeacher();
javaTeacher.수업시작();
PythonTeacher pythonTeacher = new PythonTeacher();
pythonTeacher.수업시작();
}
}
이런식으로 구성이 될 것이다.
하지만, JavaTeacher와 PythonTeacher, Teacher 클래스들은 중복된 코드가 존재한다.
그래서, 이 중복된 코드를 줄이기 위해 Teacher에 강의하기 메소드를 선언하여
자식들이 강의하기에 관해 각각 구현하게끔 미루는 작업을 수행한다.
public abstract class Teacher {
private void 입장하기(){
System.out.println("입장하기");
}
private void 출석부르기(){
System.out.println("출석부르기");
}
abstract void 강의하기();
private void 퇴장하기(){
System.out.println("퇴장하기");
}
public void 수업시작(){
입장하기();
출석부르기();
강의하기();
퇴장하기();
}
}
즉, 강의하기와 같이 정의되지 않은 것들을 자식에게 미루고 나머지 메서드는 탬플릿으로 사용한다.
저렇게 Teacher를 추상 클래스로 등록하면 JavaTeacher와 PythonTeacher는 아래와 같이 변경이 가능하다.
JavaTeacher
public class JavaTeacher extends Teacher{
// 재정의
void 강의하기(){
System.out.println("Java 강의하기");
}
}
PythonTeacher
public class PythonTeacher extends Teacher{
// 재정의
void 강의하기(){
System.out.println("Python 강의하기");
}
}
중복된 코드가 사라진 것을 알 수 있다.
근데 여기서 중요한 점이 있다.
JavaTeacher, PythonTeacher에서 강의하기를 재정의한 것은 오버라이드와는 조금 다르다.
오버라이드는 "무효화" 라는 것으로 오버라이드(부모의 메서드를 무효화하다.) 재정의와는 조금 다르다.
abstract void 강의하기();
즉, 자식 클래스가 강의하기를 재정의하면 실행시 자동으로 오버라이드 되고
Teacher의 자식인 JavaTeacher의 강의하기 메서드가 실행된다.
이걸 강의하기 메서드가 동적 바인딩된 것이라고 한다.
그래서 App 클래스도 다음과 같이 수정할 수 있다.
App
public class App {
public static void start(Teacher t){
t.수업시작();
}
public static void main(String[] args) {
JavaTeacher javaTeacher = new JavaTeacher();
start(javaTeacher);
PythonTeacher pythonTeacher = new PythonTeacher();
start(pythonTeacher);
}
}
훨씬 객체지향적 설계가 되었다.
여기까지 탬플릿 메서드 패턴에 관해 알아보았다.
'Design Pattern' 카테고리의 다른 글
[Design Pattern] 팩토리 패턴 (0) | 2024.04.04 |
---|---|
[Design Pattern] 데코레이터 패턴 (0) | 2024.04.01 |
[Design Pattern] 싱글톤 패턴 (0) | 2024.03.25 |
[Design Pattern] 어댑터 패턴 (0) | 2024.03.18 |
[Design Pattern] 프록시 패턴 (0) | 2024.03.12 |