Tenho uma aplicação JSF + JPA que eu dividi em 3 camadas. Os managed beans que interagem com a UI, os repositórios que são a camada de persistência, as classes de entidade que representam o modelo e algumas classes que serviço que tratam das regras de negócio.
A aplicação é uma aplicação de diário oficial, a seguir tenho a classe de serviço do diário, com as seguintes regras de negocio: -Incluir : a data de circulação deve ser única e apenas administradores podem criar diários -Alterar: apenas administradores podem alterar, só pode alterar se o diário ainda estiver aberto e deve garantir que a data de circulação seja única -Fechar: só administradores podem fechar o diário, só pode fechar um diário que esteja aberto e garantir as mesmas condições de "alterar diário"
A classe está assim:
@Stateless
public class DiarioService {
@EJB
private DiariosRepository diariosRepository;
public Diario salvarDiario(Diario diario, Usuario usuario){
if(!usuario.getRole().equals(Role.ADMINISTRADOR)){
throw new RuntimeException("Apenas administradores podem gerar diários");
}
diario.setUsuarioCriacao(usuario);
diario.setNumero(diariosRepository.numeroProximaPublicacao());
Diario diariocirculacao = diariosRepository.buscarDiarioPorDataCirculacao(diario.getDataCirculacao());
if(diariocirculacao != null){
throw new RuntimeException("Já existe um diário criado com esta data de circulação");
}
diariosRepository.salvarDiario(diario);
return diario;
}
public Diario alterarDiario(Diario diario, Usuario usuario){
if(!usuario.getRole().equals(Role.ADMINISTRADOR)){
throw new RuntimeException("Apenas administradores podem editar diários");
}
Diario diarioAux = diariosRepository.findByPrimaryKey(diario.getDiarioId());
if(diarioAux != null && diarioAux.isFechado() ){
throw new RuntimeException("Não é possivel editar diários já fechados");
}
Diario diariocirculacao = diariosRepository.buscarDiarioPorDataCirculacao(diario.getDataCirculacao());
if(diariocirculacao != null && !diariocirculacao.equals(diario)){
throw new RuntimeException("Já existe um diário criado com esta data de circulação");
}
diariosRepository.alterarDiario(diario);
return diario;
}
public Diario fecharDiario(Diario diario, Usuario usuario){
diario.setDataFechamento(new Date());
alterarDiario(diario, usuario);
return diario;
}
}
e tenho a classe MateriaService com as seguintes regras:
1-só pode incluir matérias em diários abertos 2- só pode alterar matérias em diários abertos, apanas administradores ou o próprio usuário que incluiu a matéria podem edita-lá e se quem editou foi um adminstrador, devo salva-ló como revisor
@Stateless
public class MateriaService {
@EJB
private MateriasRepository materiasRepository;
@EJB
private DiariosRepository diariosRepository;
public Materia salvarMateria(Materia materia, Usuario usuario){
boolean diarioAberto = diariosRepository.diarioEstaAberto(materia.getDiario().getDiarioId());
if(!diarioAberto){
throw new RuntimeException("Esta edição do diário já fechou ");
}
materia.setMatriculaInclusao(usuario.getMatricula());
materia.setSetorOrigem(usuario.getSetor());
materiasRepository.salvarMateria(materia);
return materia;
}
public Materia alterarMateria(Materia materia, Usuario usuario){
boolean diarioAberto = diariosRepository.diarioEstaAberto(materia.getDiario().getDiarioId());
if(!diarioAberto){
throw new RuntimeException("Esta edição do diário já fechou ");
}
if(!materia.permiteModificacao(usuario)){
throw new RuntimeException("Apenas Administradores ou o próprio usuário que criou a matéria pode editar");
}
if(usuario.getRole().equals(Role.ADMINISTRADOR)){
materia.setMatriculaRevisao(usuario.getMatricula());
}
materiasRepository.alterarMateria(materia);
return materia;
}
}
Oque me incomoda um pouco é ficar passando esse usuário para a classe de serviço e toda hora ficar checando o perfil dele para realizar alguma ação. Este tipo de código deve ficar na classe de serviço mesmo ou deveria estar no ManagedBean?
Outra coisa que eu não sei se é muito bacana é quando eu faço nas classes de serviço
materia.setMatriculaInclusao(usuario.getMatricula());
materia.setSetorOrigem(usuario.getSetor());
ou
diario.setDataFechamento(new Date());
falando em Solid é teóricamente correto eu ter este tipo de código dentro das classes de serviço ou estas devem apanas fazer a orquestração dos objetos?