Saudações!!
Estou com uma dúvida em modelar funções dentro do sistema... Por enquanto tenho apenas duas funções (Aluno e Porfessor). Eu deveria utilizar herança para modelar isso? Ex:
abstract class Usuario {
abstract public boolean isProfessor();
//outros comportamentos e atributos de usuario
}
class Professor extends Usuario {
@Override
public boolean isProfessor() {
return true;
}
}
class Aluno extends Usuario{
@Override
public boolean isProfessor() {
return false;
}
}
Ou então com uma única classe representando Usuário e um ENUM indicando a função dele? ex:
enum Funcao {
ALUNO, PROFESSOR;
}
class Usuario {
private Funcao funcao;
public Usuario(Funcao funcao) {
this.funcao = funcao;
}
public Funcao getFuncao() {
return funcao;
}
//outros comportamentos e atributos de usuario
}
O ponto aqui é que o professor terá acesso a alguns lugares que o aluno não terá. Então em alguns pontos do sistema eu tenho que verificar se o usuario que esta tentando acessar é um Aluno ou um Professor.
Como o Aluno tem um comportamento diferente do Professor imaginei que ambos fossem classes diferentes... Mas não faz muito sentido eu perguntar pro usuário algo do tipo:
Usuario usuario = //recupera o usuario de algum lugar
if(!usuario.podeAcessar(lugarOndeApenasAlgunsAlunosPodemAcessar))
throw new VoceNaoPodeAcessarException();
O lugarOndeApenasAlgunsAlunosPodemAcessar saberia que apenas alguns alunos específicos podem acessar (talvez com uma lista de ids ou algo do tipo). Dessa forma o meu objeto usuário teria que chamar um método e saber de um atributo (estado) interno do objeto que quero acessar... Já li em alguns lugares: "Se quer saber algo sobre os atributos do objeto, pergunte pra ele!". ex:
class Usuario {
//...
public boolean podeAcessar(LugarAcessivel lugarAcessivel){
if(lugarAcessivel.getListaDeUsuariosQuePodemAcessar().contains(this))
return true;
else if(funcao.equals(Funcao.PROFESSOR)) //Se for professor, pode acessar (com herança se chamaria isProfessor())
return true;
else
return false;
}
}
Então pensei no seguinte:
Usuario usuario = //recupera o usuario de algum lugar
if(!lugarOndeApenasAlgunsAlunosPodemAcessar.podeSerAcessadoPor(usuario))
throw new VoceNaoPodeAcessarException();
Só que nesse caso também teríamos que saber de um atributo (estado) do objeto Usuario para fazer alguma coisa... O que também não faz sentido... Pois, se quero saber algo do objeto, pergunte pra ele! ex:
class LugarAcessivel {
private List<Usuario> usuariosQuePodemAcessar;
//...
public boolean podeSerAcessadoPor(Usuario usuario) {
if(usuariosQuePodemAcessar.contains(usuario))
return true;
else if(usuario.getFuncao().equals(Funcao.PROFESSOR)) //Se for professor, pode acessar (com herança se chamaria isProfessor())
return true;
else return false;
}
}
Note que nesse segundo exemplo o isProfessor faria mais sentido... (nao seria necessário pegar a funçao do usuario e compará-la... basta perguntar pro usuario)
Enfim, o que vocês acham dessa modelagem? Acha que existe uma melhor forma de modelar algo desse tipo?
Gostaria de ouvir (ler) a opinião de vocês!
Até!