본문으로 바로가기
728x90
반응형
SMALL

본 교재를 기반으로 정리합니다.

 

일부 구현만 다를뿐 완전 동일한 절차를 가진 코드가 있을때

 

DB데이터와 LDAP를 이용해서 인증을 처리하는 클래스들

DB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class DbAuthenticator {
 
    public Auth authenticate(String id, String pw){
 
        //사용자 인증정보 확인
        User user = userDao.selectById(id);
        boolean auth = user.equalPassword(pw);
        
        //인증 실패시 예외 발생
        if(!auth)
            throw createException();
            
            return new Auth(id, user.getName());        
    }
 
    private AuthException createException(){
        return new AuthException();
    }
}
cs

LDAP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class LdapAuthenticator {
 
    public Auth authenticate(String id, String pw){

        //사용자 인증정보 확인
        boolean lauth = ldapClient.authenticate(id, pw)
        //인증 실패시 예외 발생
        if(!auth)
            throw createException();
            
            LdapContext ctx = ldapClient.find(id);
            return new Auth(id, ctx.getAttribute("name"));    
    }
 
    private AuthException createException(){
        return new AuthException();
    }
}
cs

 

실행 과정/단계는 동일한데 각 단계 중 일부의 구현이 다른 경우 사용할 수 있는 패턴이 템플릿 메서드 패턴이다.

템플릿 메서드는 2가지로 구성된다.

  • 실행 과정을 구현한 상위 클래스
  • 실행 과정의 일부 단계를 구현한 하위 클래스

상위 클래스는 실행 과정이 동일한 메서드 + 구현이 다른 추상 메서드를 구성하여 만든다.

템플릿 메서드를 제공하는 Authenticator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public abstract Authenticator {
    
    //템플릿 
    public Auth authenticate(String id, String pw){
        if(!doAuthenticate(id, pw))
            throw createException();
            
        return createAuth();            
    }
 
    protected abstract boolean doAuthenticate(String id, String pw);
 
    private RuntimeException createException(){
        throw new AuthException();
    }
    
    protected abstract Auth createAuth(String id);
    
}
cs

4줄 authenticate() 메서드는 DB LDAP 에서 동일했던 실행과정을 구현했고

두 클래스에서 차이가 나는 부분은 별도의 추상 메서드로 분리했다.

authenticate() 메서드는 모든 하위 타입에 동일하게 적용되는 실행 과정을 제공하기 때문에 템플릿 메서드라고 부른다.

 

Authenticator 클래스를 상속받은 하위 클래스는 abstract 가 붙은 메서드들만 재정의 해주면 된다.

 

템플릿 메서드 패턴을 적용한 LdapAuthenticator의 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class LdapAuthenticator extends Authenticator {
    
    @Override
    protected boolean doAuthenticate(String id, String pw){
        return ldapClient.authenticate(id, pw);
    }
 
    @Override
    protected Auth createAuth(String id){
        LdapContext ctx = ldapClient.find(id);
        return new Auth(id, ctx.getAttribute("name"));
    }
    
}
cs

LdapAuthenticator 클래스는 이제 전체 실행 과정 구현을 제공하지 않고 일부 과정의 구현만을 제공한다.

 템플릿 메서드의 경우 외부에 제공하는 기능에 해당되기 때문에 public 범위를 가져야하는 반면에

doAuthenticate() 메서드나 createAuth()메서드는 템플릿 메서드에서만 호출되어야 하기 때문에 public 일 필요가 없으며

이 두 메서드는 하위타입에서 재정의 할 수 있어야 하기 때문에 private가 아닌 protected의 범위를 가져야 한다.

 

 

템플릿 메서드 패턴을 사용하면

동일한 실행 과정의 구현을 제공하면서 동시에 하위 타입에서 일부 단계를 구현하도록 할 수 있다. 이는 각 타입에서 코드가 중복되는 것을 방지한다.

 

일반적인 경우는 하위 타입이 상위 타입의 기능을 재사용할지 여부를 결정하지만

템플릿 메서드의 패턴의 특징은 하위 클래스가 아닌 상위 클래스에서 흐름제어를 한다는것이다.

 

 



 

728x90
반응형
LIST