Java

[Design Pattern] 템플릿 메소드 패턴(Template Method Pattern)

구루싸 2020. 6. 11. 21:46
반응형
SMALL

오늘 하루도 어느덧 저물어 가네요

날씨가 더워져서 코로나19로 인한

마스크 착용이 더욱 괴롭게 느껴집니다

하루 빨리 코로나19에 대한

백신이 개발되어 안정되기 바랍니다

아무튼 오늘도 디자인 패턴 학습을 진행하겠습니다

주제는 템플릿 메소드 패턴입니다

템플릿은 잘 아시다시피

일정한 틀, 형식을 의미하는데

이번 패턴은 템플릿의 기능을 가진 패턴입니다

구체적으로는 상위 클래스가 템플릿이되고

하위 클래스에서 구체적인 구현
내용을 결정하는 것입니다

먼저 템플릿 메소드 패턴을 구성하는

역할들을 정리하고 시작하겠습니다

역할설명
추상 클래스(Abstract Class)템플릿 메소드를 구현
구현 클래스(Concrete Class)추상 클래스 역할에서 정의되어 있는 추상 메소드를 구체적으로 구현

템플릿 메소드 패턴을 구성하는

역할은 비교적 간단하네요~

자 그럼 구현을 해보겠습니다
추상 클래스 역할을 수행하는
AbstractDisplay 클래스를 하나 생성하고
이 클래스를 상속 받는 클래스를 생성합니다

1. 클래스(Class) AbstractDisplay.java

package TemplateMethodPattern;

public abstract class AbstractDisplay {
	public abstract void open();
	public abstract void print();
	public abstract void close();
	public final void display() {
		open();
		for ( int i = 0; i < 5; ++i ) {
			print();
		}
		close();
	}
}

2. 클래스(Class) CharDisplay.java

package TemplateMethodPattern;

public class CharDisplay extends AbstractDisplay {
	private char ch;
	public CharDisplay(char ch) {
		this.ch = ch;
	}
	public void open() {
		System.out.print("<<");
	}
	public void print() {
		System.out.print(ch);
	}
	public void close() {
		System.out.println(">>");
	}
}

3. 클래스(Class) StringDisplay.java

package TemplateMethodPattern;

public class StringDisplay extends AbstractDisplay {
	private String string;
	private int width;
	public StringDisplay(String string) {
		this.string = string;
		this.width = string.getBytes().length;
	}
	public void open() {
		printLine();
	}
	public void print() {
		System.out.println("|" + string + "|");
	}
	public void close() {
		printLine();
	}
	private void printLine() {
		System.out.print("+");
		for ( int i = 0; i < width; ++i ) {
			System.out.print("-");
		}
		System.out.println("+");
	}
}

4. 클래스(Class) Test.java

import TemplateMethodPattern.*;

public class Test {
	public static void main(String[] args) {
		/* Template Method Pattern */
		AbstractDisplay displayChar = new CharDisplay('T');
		AbstractDisplay displayString = new StringDisplay("Template Method Pattern");
		displayChar.display();
		displayString.display();
	}
}

위의 코드를 살펴보면

추상 클래스 AbstractDisplay가

템플릿 메소드 패턴의 추상 클래스 역할로

하위 클래스에서 open(), print(), close()를

구현하도록 하고 있습니다

그리고 display() 메소드에서

세 메소드가 어떻게 동작하는지
알고리즘을 정의하고
이 display() 메소드를

final 키워드를 이용하여 하위 클래스에서
오버라이딩(overriding) 할 수 없게 합니다

Test 클래스에서 실제로 사용할 때는

AbstractDisplay 형 변수에
하위 클래스 객체를 대입하고

단지 display()를 호출합니다
이러면 하위 클래스에서 구현한
open(), print(), close()가
display()에 작성된 순서대로 동작합니다
이렇게 함으로써 상위 클래스인
AbstractDisplay는 하위 클래스에게
구현을 맡기고 자신이 원하는 순서로
프로그램이 동작하도록 하는데 성공합니다

왜 이렇게 작성하는 것일까요?

만약에 CharDisplay와 StringDisplay 클래스를

각각 따로 복사 & 붙여넣기 했고

CharDisplay에서 오류가 발생다면

CharDisplay와 StringDisplay 모두를 수정해야합니다

Concrete Class가 많다면 욕나오겠죠-_-

그런데 이 패턴은 상위 클래스와 하위 클래스가

서로 긴밀하게 작동하고 있습니다

이 얘기는 만약 상위 클래스의 소스를 모른다면

정말 난감한 상황이 발생할 수 있다는 것입니다

여기서 잠깐 참고로 Test 클래스에서

상위 클래스 AbstractDisplay형 변수에

하위 클래스 CharDisplay와 StringDisplay를 대입하는데

이것은 상속의 일반적인 원칙인

LSP(The Liskov Substitution Principle)의 적용입니다

추상 클래스가 등장하면 인터페이스가 생각납니다

그럼 이런 의문이 생길 수 있는데요

이 패턴에 인터페이스를 사용할 수는 없는가?

불가합니다 이유는 display() 메소드에 있는데

인터페이스는 구체적인 구현을 담은

메소드가 있을 수 없기 때문입니다

자바를 학습하면 어쩌면 자연스럽게 알고 있었을 내용이라

이번 주제는 비교적 난이도 낮았던거 같네요

지난 학습이 궁금하시다면 아래의 링크↓

2020/06/08 - [Java] - [Design Pattern] 반복자 패턴(Iterator Pattern)

[Design Pattern] 반복자 패턴(Iterator Pattern)

아직 6월 초인데 한 여름 마냥 날씨가 급격하게 더워져서 출퇴근 길에 땀이 흥건...하... 30도 가까이 되는 지역도 있더라고요 코로나19도 끝날 기미가 보이지 않는데 몸 관리 잘하시길 바랍니다 ��

yssa.tistory.com

2020/06/09 - [Java] - [Design Pattern] 어댑터 패턴(Adapter Pattern)

[Design Pattern] 어댑터 패턴(Adapter Pattern)

오늘 하루도 끝나가네요-_- 시간은 왜 이리도 빠른지 도전해 보고 싶은 것은 많은데 나이만 먹는거 같네요ㅜㅜ 아무튼 오늘은 지난 시간에 이어서 디자인 패턴 중 어댑터 패턴에 대해 학습하겠��

yssa.tistory.com

 

아무튼 이것으로 이번 학습을 마치겠습니다

그럼 이만-_-

 

반응형
LIST