1
In an application for user authentication via Radius I thought it would be interesting to use Design Patter Strategy with Enum.
So the code went like this:
public enum TipoAutenticacao {
LIVRE("Acesso Livre"){
@Override
public String autentica(LoginService service, String user, String mac) throws NoResultException, AccessException{
Login login = service.findByUser(user);
return login.autentica(user, login.getPass());
}
},
MAC("Filtro de MAC"){
@Override
public String autentica(LoginService service, String user, String mac) throws NoResultException, AccessException{
Login login = service.findByUser(user);
return login.autentica(user, login.getPass(), mac);
}
};
private String descricao;
TipoAutenticacao(String descricao){
this.descricao = descricao;
}
public String getDescricao(){
return this.descricao;
}
public abstract String autentica(LoginService service , String user, String mac) throws NoResultException, AccessException;
}
Method autentica
in the Login
public String autentica(String user, String pass, String mac) throws AccessException {
if(!this.mac.equals(mac))
throw new AccessException(TipoLoginResposta.MAC_INVALID);
return autentica(user, pass);
}
public String autentica(String user, String pass) throws AccessException {
if(!this.user.equals(user) || !this.pass.equals(pass))
throw new AccessException(TipoLoginResposta.USER_PASS_INVALID);
if(bloqueado)
throw new AccessException(TipoLoginResposta.BLOQUEADO);
if(!this.getUsuario().isPendenciaFinanceira())
throw new AccessException(TipoLoginResposta.PENDENCIA_FINANCEIRA);
return this.pass;
}
TipoLoginResposta
public enum TipoLoginResposta {
USER_PASS_INVALID("Login/Senha Inválidos"),
MAC_INVALID("MAC Inválido"),
PENDENCIA_FINANCEIRA("Pendência Financeira"),
BLOQUEADO("Bloqueado");
private String descricao;
TipoLoginResposta(String descricao){
this.descricao = descricao;
}
public String getDescricao(){
return this.descricao;
}
}
The idea of using the AccessException
passing the builder TipoLoginResposta
is to be specified later in the database why the user could not connect.
Using this implementation I’m tying the code somehow?
In the case of
TipoAutenticacao
if it can avoid being aenum
better, in my opinion two classes that implement an interface with the method are enoughautentica()
.– Piovezan
But if you need to add other ways to authenticate? I would have to have a class for each type of authentication.. This would generate several classes, no?
– SoabTI
It would generate, just as in the current way you would need several instances of Enum Typo. But without violating the open/closed principle, because it would not be changing an Enum but adding classes.
– Piovezan
Not directly related to the question, but why do you copy much of the code between the
autentica
with 2 or 3 parameters? Wouldn’t it be better to do something like{ if(!this.mac.equals(mac)) throw ...; return autentica(user, pass); }
The order of the tests would be slightly altered, however, maybe not what you need, but stay there as a suggestion.– mgibsonbr
@Piovezan Thanks! I will consider your tip. This open/closed principle is the right SOLID concept? I’m going to study it.
– SoabTI
@mgibsonbr Really! I applied this to other parts of the code, but I missed that part. Thank you!
– SoabTI