템플릿 메서드(Template Method)
- Def) 알고리즘의 구조를 메소드에 정의하고 하위 클래스에서 알고리즘 구조의 변경없이 알고리즘을 재정의하는 패턴
- 부모 클래스에서 알고리즘의 골격을 정의하지만 해당 알고리즘의 구조를 변경하지 않고 자식 클래스들이 알고리즘의 특정 단계를 오버라이드할 수 있도록 하는 행동 디자인 패턴을 말한다.
- 사용하는 경우
- 구현하려는 알고리즘이 일정한 프로세스가 있다. 여러 단계가 있다.
- 구현하려는 알고리즘이 변경 가능성이 있다.
템플릿 메서드 사용 방법
- 알고리즘을 여러 단계로 나눈다.
- 나눠진 알고리즘의 단계를 메소드로 선언한다.
- 알고리즘을 수행한 템플릿 메소드를 만든다.
- 하위 클래스에서 나눠진 메소드들을 오버라이드한다.
기본 설계
- 추상 클래스에 step1, 2, 3 을 나눠서 다음과 같이 추상 메서드로 선언한다.
- step1, 2, 3에 해당하는 메서드들을 템플릿 메서드에서 호출한다.
- 즉, 템플릿 메서드는 구현부가 있다.
- 하위 클래스에서 메서드를 재정의한다.
Ex) 신작 게임의 접속을 구현하라
- 보안 과정: 보안 관련 부분을 처리한다.
- 인증 과정: user name과 password가 일치하는지 확인한다.
- 권한 과정: 접속자가 유료 회원인지 무료 회원인지 게임 마스터인지 확인한다.
- 접속 과정: 접속자에게 커넥션을 정보로 넘겨준다.
- 추상 클래스 구현하기 - abstractGameHelper
- 하위 클래스가 메서드들을 재정의해야하므로 접근 제어자를 private로 설정하지 않는다.
- request 메서드는 네 가지 단계(보안, 인증, 권한, 접속)로 이뤄져 있다.
- 메서드 패턴에서 네 가지를 불러준다.
<hide/>
public abstract class AbstractGameConnectHelper {
protected abstract String doSecurity(String string);
protected abstract boolean authorization(String id, String password);
protected abstract int authorization(String username);
protected abstract String connection(String info);
// 템플릿 메서드
public String requestConnection(String encodedInfo) {
String decodedInfo = doSecurity(encodedInfo); // 보안 작업 => 암호화된 문자열을 복호화
String id = "userId";
String password = "1234!@";
if (!authorization(id, password)) {
throw new Error("아이디 암호 불일치");
}
String userName = "userName";
int authIndex = authorization(userName); // 권한 번호
switch (authIndex) {
case 0: // 게임 매니저
break;
case 1: // 유료 회원
break;
case 2: // 무료 회원
break;
case 3: // 권한 없음
break;
default: // 기타 상황
break;
}
return connection(decodedInfo);
}
}
- 구체화 클래스 DefaultGameConnectHelper
- 하위 클래스에서 구현해준다.
- 패키지를 따로 나눠서 클래스를 분리해주면 위에서 protected로 접근 제한자를 지정해줬기 때문에 다음 코드의 helper 까지 구현했을 때, request 를 제외한 다른 메서드는 나오지 않는다.
<hide/>
package dp;
public class DefaultGameConnectHelper extends AbstractGameConnectHelper {
@Override
protected String doSecurity(String string) {
System.out.println("= decode =");
return null;
}
protected boolean authentication(String id, String password) {
System.out.println("= 아이디/암호 확인 과정");
return true;
}
@Override
protected int authorization(String username) {
System.out.println("= 권한 확인 =");
// 서버에서 유저 이름을 가지고 나이를 확인해서 시간을 확인하고 성인이 아니고 10시가 지났다면
// 권한이 없는 것으로
return -1;
}
@Override
protected String connection(String info) {
System.out.println("= 마지막 접속 단계! =");
return null;
}
}
- Main
<hide/>
public static void main(String[] args) {
AbstractGameConnectHelper helper = new DefaultGameConnectHelper();
helper.requestConnection("아이디 암호 등 접속 정보");
}
Ex) 추가 요구 사항 - 셧다운제
- 보안 부분 강화
- 밤 10시 이후 접속이 제한 되도록 한다.
- Default 클래스를 다음과 같이 바꾼다.
<hide/>
@Override
protected int authorization(String username) {
System.out.println("= 권한 확인 =");
// 서버에서 유저 이름을 가지고 나이를 확인해서 시간을 확인하고 성인이 아니고 10시가 지났다면
// 권한이 없는 것으로
return -1;
}
case -1: //
throw new Error("셧다운");
궁금한 점 및 기타
- 결국 템플릿 메소드 패턴은 데이터베이스의 프로시저와 비슷한 개념?
- (인터페이스는 추상 메서드로만 이뤄져 있는 것과 다르게 추상클래스에는 멤버 변수, 구현부를 포함한 메서드를 포함할 수 있다.)
출처
https://www.inflearn.com/course/lecture?courseSlug=%EC%9E%90%EB%B0%94-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4&unitId=3175
'디자인 패턴 (Design Pattern)' 카테고리의 다른 글
[구조 패턴] 퍼사드 패턴(Facade pattern) (0) | 2023.03.13 |
---|---|
[구조 패턴] 데코레이터 패턴(Decorator pattern, 장식자) (0) | 2023.03.12 |
[행동 패턴] 커맨드 패턴(Command Pattern, 명령 패턴) (0) | 2023.02.27 |
[행동 패턴] 전략 패턴(Strategy Pattern) (0) | 2023.02.27 |
[개요] 디자인패턴(Design Pattern)이란? (0) | 2023.01.28 |