아무거나

[Design Pattern] Template Method Pattern 본문

Java & Kotlin/Java

[Design Pattern] Template Method Pattern

전봉근 2019. 12. 7. 16:24
반응형

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

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

  • 사용
    • 구현하려는 알고리즘이 일정한 프로세스가 있다.
    • 구현하려는 알고리즘이 변경 가능성이 있다.
  • 단계
    • 알고리즘을 여러 단계로 나눔 ( Abastract Class )
    • 나눠진 알고리즘의 단계를 메소드로 선언 ( Abastract Class의 operation1() ~ 3() )
    • 알고리즘을 수행할 템플릿 메소드를 만듬 ( Abastract Class의 templateMethod() )
    • 하위 클래스에서 나눠진 메소드들을 구현 ( ConcreteClass )

템플릿 메소드 패턴 예시 - 1

  • 신작 게임의 접속을 구현
    • requestConnection(String str):String
  • 유저가 게임 접속시 아래 목록을 고려
    • 보안과정: 보안 관련 부분 처리
      • doSecurity(String string):String
    • 인증과정: user name과 password 일치여부 확인
      • authentication(String id, String password):boolean
    • 권한과정: 접속자가 유료 회원인지 무료 회원인지 게임 마스터인지 확인
      • authorization(String userName):int
    • 접속과정: 접속자에게 커넥션 정보를 넘겨준다.
      • connection(String info):String

여기서 이미 보안,인증,권한,접속 과정으로 알고리즘을 여러단계로 나눈걸 확인할 수 있다. 또한 나눠진 알고리즘의 단계를 doSecurity, authentication 등. 나눠진 알고리즘의 단계를 메소드로 선언한 걸 확인할 수 있다. 그리고 requestConnection 메소드는 알고리즘을 수행할 템플릿 메소드가 만들어져 있는 것이다.

이제 하위 클래스에서 나눠진 메소드를 구현해보자.

추상클래스를 만들자. [AbstGameConnectHelper.java]

package com.bkjeon.template_method;

public abstract class AbstGameConnectHelper {
    /*
        외부에서는 호출하면 안되는데 하위 클래스에서 사용할 수 있게 protected를 사용해야 된다.
     */
    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 decodedInfo = doSecurity(encodedInfo);

        // 반환된 것을 가지고 아이디, 암호를 할당
        String id = "aaa";
        String password = "bbb";

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

        String userName = "userName";
        int i = authorization(userName);

        // 권한
        switch (i) {
            case 0:
                System.out.println("게임 매니저");
                break;
            case 1:
                System.out.println("유료 회원");
                break;
            case 2:
                System.out.println("무료 회원");
                break;
            case 3:
                System.out.println("권한 없음");
                break;
            default:
                System.out.println("기타 상황");
                break;
        }

        // 접속
        return connection(decodedInfo);
    }
}

그 다음 추상클래스를 구현해보자. [DefaultGameConnectHelper.java]

package com.bkjeon.template_method;

public class DefaultGameConnectHelper extends AbstGameConnectHelper {
    @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;
    }
}

doSecurity, authentication, authorization, connection 의 네가지의 단계로 이루어져있는 것을 requestConnection 라는 메소드 패턴에서 불러주고 그 다음엔 하위클래스인 DefaultGameConnectHelper 에서 구체적인 정보를 구현

메인 클래스 작성 [Main.java]

package com.bkjeon.template_method;

public class Main {

    public static void main(String[] args) {
        AbstGameConnectHelper helper = new DefaultGameConnectHelper();
        helper.requestConnection("아이디 암호 등 접속 정보");
    }

}

실행결과

디코드
아이디/암호 확인 과정
권한 확인
게임 매니저
마지막 접속단계!

위에는 동일한 패키지라서 protected가 접근이 가능하지만 패키지를 나눠야 접근이 불가하다. (AbstGameConnectHelper, DefaultGameConnectHelper을 다른 패키지로 이동시키고 Main클래스에서 자동완성을 확인해보면 접근이 불가하다.)

템플릿 메소드 패턴 예시 - 2

  • 보안 부분이 정부 정책에 의해서 강화 되었다. 강회된 방식으로 코드를 변경하자.
  • 밤 10시 이후에 접속이 제한 되도록 셧다운 제도를 적용하자.

구현 단계로 가서 보안 단계를 강화하자. [DefaultGameConnectHelper.java]

package com.bkjeon.template_method.lib;

public class DefaultGameConnectHelper extends AbstGameConnectHelper {
    @Override
    protected String doSecurity(String string) {
//        System.out.println("디코드");
        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;
    }
}

그 다음 셧다운 제도를 적용하자. [AbstGameConnectHelper.java]

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

        // 권한
        switch (i) {
            // 추가
            case -1:
                throw new Error("셧다운");
            case 0:
                System.out.println("게임 매니저");
                break;

        ...
    }
    ...

[DefaultGameConnectHelper.java]

package com.bkjeon.template_method.lib;

public class DefaultGameConnectHelper extends AbstGameConnectHelper {
    @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("권한 확인");
        System.out.println("권한 확인");
        // 서버에서 유저 이름을 가지고 유저의 나이를 알 수 있다.
        // 나이를 확인하고 시간을 확인해서 성인이 아니고 10시가 지났다면
        // 권한이 없는 것으로 한다.
        return 0;
    }

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

실행결과

강화된 알고리즘을 이용한 디코드
아이디/암호 확인 과정
권한 확인
게임 매니저
마지막 접속단계!

 

참고: https://www.inflearn.com/course/%EC%9E%90%EB%B0%94-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4/dashboard

반응형

'Java & Kotlin > Java' 카테고리의 다른 글

[Design Pattern] Singleton Pattern  (0) 2019.12.07
[Design Pattern] Factory Method Pattern  (0) 2019.12.07
[Design Pattern] Strategy Pattern  (0) 2019.12.07
[Design Pattern] Adapter Pattern  (0) 2019.12.07
[Design Pattern] Strategy Pattern  (0) 2019.10.27
Comments