본문 바로가기

CS/DesignPattern

(DesignPattern) 템플릿 메서드 패턴

템플릿 메서드 패턴이란?

알고리즘 구조를 메서드에 정의하고 하위 클래스에서 알고리즘 구조의 변경 없이 해당 알고리즘을 재 정의하는 패턴

 

When?

  • 구현하려는 알고리즘이 일정한 프로세스가 있을 때
  • 구현하려는 알고리즘이 변경 가능성이 있을 때

How?

  1. 알고리즘을 여러 단계로 나눈다.
  2. 나뉜 알고리즘의 단계를 메서드로 선언한다.
  3. 알고리즘을 수행할 템플릿 메서드를 만든다.
  4. 하위 클래스에서 나뉜 메서드들을 구현한다.

구현

요구사항

신작 게임의 접속을 구현해보자

 

유저는 게임 접속 하위와 같은 로직을 구현해야 한다.

  • 보안 과정 : 보안 관련 부분을 처리
  • 인증 과정 : user_name과 password가 일치하는지 확인
  • 권한 과정 : 접속자가 유료회원인지 무료회원인지 게임 마스터인지 확인
  • 접속 과정 : 접속자에게 커넥션에 대한 정보를 넘겨준다.

 

추상 클래스 생성

  • protected 접근자로 상속받은 클래스만 해당 메서드를 구현할 수 있도록 강제
  • 일정한 프로세스에 따라 구현하기 위한 템플릿 메서드 생성
public abstract class AbstractGameConnectHelper {
    

    /*보안 과정*/
    protected abstract String doSecurity(String string);
    /*인증 과정*/
    protected abstract boolean authentication(String id, String password);
    /*권한 과정*/
    protected abstract int authorization(String userName);
    /*접속 과정*/
    protected abstract String connection(String info);


    // 템플릿 메서드
    public String requestConnection(String encodedInfo) {



        return connection(decodedeInfo);
    }
}

 

템플릿 메서드 로직 구현

public abstract class AbstractGameConnectHelper {

    private static final Map<Integer, String> AUTHORIZATION;

    static {
        final Map<Integer, String> authorization = new HashMap<>();
        authorization.put(0, "게임 매니저");
        authorization.put(1, "유료 회원");
        authorization.put(2, "무료 회원");
        authorization.put(3, "권한 없음");

        AUTHORIZATION = Collections.unmodifiableMap(authorization);
    }

    /*보안 과정*/
    protected abstract String doSecurity(String string);
    /*인증 과정*/
    protected abstract boolean authentication(String id, String password);
    /*권한 과정*/
    protected abstract int authorization(String userName);
    /*접속 과정*/
    protected abstract String connection(String info);


    // 템플릿 메서드
    public String requestConnection(String encodedInfo) {
        String decodedeInfo = doSecurity(encodedInfo);
        String id = "mike6321";
        String password = "junwoo";

        if (!authentication(id, password)) {
            throw new Error("아이디 암호 불 일 치");
        }

        String userName = "userName";
        int authorization = authorization(userName);
        System.out.println(AUTHORIZATION.get(authorization));


        return connection(decodedeInfo);
    }
}

구현 클래스 생성

public class DefaultGameConnectionHelper extends AbstractGameConnectHelper{
    @Override
    protected String doSecurity(String string) {
        System.out.println("디코드...");

        return string;
    }

    @Override
    protected boolean authentication(String id, String password) {
        System.out.println("아이디/암호 확인 과정...");

        return true;
    }

    @Override
    protected int authorization(String userName) {
        System.out.println("권한 확인...");

        return 0;
    }

    @Override
    protected String connection(String info) {
        System.out.println("마지막 접속 단계...!");

        return info;
    }
}

 

실행 결과


추가 요구사항

  • 보안이 강화되어 강화된 방식으로 코드 구현
  • 여성가족부에서 밤 10시 이후에 접속이 제한되도록 요구

템플릿 메서드 수정

authorization.put(4, "Shut Down");
if (authorization == 4)
    throw new Error("셧다운!!!");

 

구현 메서드 수정

@Override
protected int authorization(String userName) {
    System.out.println("권한 확인...");
    // TODO: [authorization] junwoochoi 2020/04/20 9:04 오후
    // 서버에서 유저 이름 혹은 유저의 나이를 알 수 있다.
    // 나이를 확인하고 시간을 확인하여 성인이 아니라면 셧 다운
    return 4;
}

 

실행 결과

이와 같이 요구 사항을 추가하더라도 구현 부분과 프로세스가 명확하게 나누어져 있기 때문에 간편하게 수정이 가능하다.

Code Link

https://github.com/mike6321/PURE_JAVA/tree/master/EffectiveStudy

 

mike6321/PURE_JAVA

Contribute to mike6321/PURE_JAVA development by creating an account on GitHub.

github.com

References

 

 

'CS > DesignPattern' 카테고리의 다른 글

(DesignPattern) 프로토타입 패턴  (0) 2020.05.04
(DesignPattern) 싱글턴 패턴  (0) 2020.05.02
(DesignPattern) 팩토리메서드 패턴  (0) 2020.04.22
(DesignPattern) 어댑터 패턴  (0) 2020.04.21
(DesignPattern) 전략 패턴  (0) 2020.04.20