Olá, estou tentando seguir as dicas do curso e tentando manter minhas classes coesas ,mas estou com uma dúvida prática, será que estou no rumo certo da OO?
Tenho a seguinte situação, uma classe chamada "Alerta", o Alerta tem uma data de publicação, ou seja o operador pode ir preenchendo os dados do alerta e ir salvando o trabalho aos poucos e por fim ele vai disponibilizar o alerta para o usuario final atráves do comando publicar(preenche a datada publicação e o autor do alerta), após publicado nenhuma alteração pode ser feita.
O alerta também tem os atributos: dataAbertura e responsavelAbertura, pois depois de publicado o usuário não pode fazer nada no sistema sem antes ler os seus alertas publicados que ainda não foram lidos.
Antes do curso eu setaria a data de publicação do alerta dentro da minha classe de serviço, mas ai estaria separando dados de comportamento.
Pensando em encapsulamento e coesão, os atributos dataPublicacao e dataAbertura não tem métodos setters, no entanto da forma que implementei achei que ficou meio estranho, pois na hora de publicar por exemplo, se ocorrer um erro no merge, o alerta ainda vai estar com a dataPublicacao setada, ai se ele depois do erro clica em salvar e PAH, publica o alerta!!
Seguindo os preceitos da OO ,minha implementação está correta? toda opinião é muito bem vinda.
@Entity
public class Alerta implements Serializable{
@Temporal(TemporalType.DATE)
@Column(name="DATA_PUBLICACAO")
private Date dataPublicacao = null;
@Temporal(TemporalType.DATE)
@Column(name="DATA_ABERTURA")
private Date dataAbertura;
@Column(name="RESPONSAVEL_ABERTURA")
private Integer usuarioAbertura;
@Column(name="RESPONSAVEL_ABERTURA")
private String matricula;
//propriedades omitidas
@Transient
public boolean isNovo(){
if(this.alertaId == null){
return true;
}
return false;
}
@Transient
public boolean isEditando(){
return !isNovo();
}
@Transient
public boolean isAGF(){
if(this.naturezaProcesso != null){
if(this.naturezaProcesso.contains("A200")){
return true;
}
}
return false;
}
@Transient
public boolean isAGR(){
if(this.naturezaProcesso != null){
if(this.naturezaProcesso.contains("A201")){
return true;
}
}
return false;
}
@Transient
public void vincularProcesso(ProcessoDTO processo){
this.numeroProcesso = processo.getNumero();
this.anoProcesso = processo.getAno();
this.naturezaProcesso = processo.getSubtipo();
}
@Transient
public String gerarPrevisualizacaoTexto(){
GeradorTextoAlerta builder = new GeradorTextoAlerta(this);
return builder.getCorpoAlerta();
}
@Transient
public void abrir(Integer responsavelId){
if(!isPublicado()){
throw new RuntimeException("Não é possível abrir um alerta que não foi publicado.");
}else{
this.dataAbertura = new Date();
this.usuarioAbertura = responsavelId;
}
}
@Transient
public boolean isFechado(){
if(this.dataAbertura == null){
return true;
}
return false;
}
@Transient
public void publicar(String usuarioFinalizacao){
if(isPublicado()){
throw new RuntimeException("O alerta já foi publicado.");
}else{
this.tecnico = usuarioFinalizacao;
this.dataPublicacao = new Date();
if(this.texto != null){
this.texto = null;
}
GeradorTextoAlerta builder = new GeradorTextoAlerta(this);
this.texto = builder.getCorpoAlerta();
}
}
@Transient
public boolean isPublicado(){
if(this.dataPublicacao != null){
return true;
}
return false;
}
@Transient
public void atribuiChave(Integer numero,Integer ano){
this.numeroAlerta = numero;
this.anoAlerta = ano;
}
public String getTexto() {
if(!isPublicado()){
throw new RuntimeException("O alerta ainda não possui texto.");
}
return texto;
}
}
@Stateless
public class AlertaBean {
@PersistenceContext(name="xxxxPU")
private EntityManager manager;
@EJB
private EnteFacade enteFacade;
@EJB
private ChaveAlertaFacade chaveFacade;
public Alerta find(Integer id){
Alerta alerta = manager.find(Alerta.class,id);
Ente ente = enteFacade.findByPrimaryKey(alerta.getEnteId());
alerta.setEnte(ente);
return alerta;
}
public void salvar(Alerta alerta){
ChaveAlerta chave = chaveFacade.find();
Integer numero = chave.getNumero();
Integer ano = chave.getAno();
alerta.atribuiChave(numero, ano);
manager.persist(alerta);
chave.incrementa();
chaveFacade.update(chave);
}
public Alerta atualizar(Alerta alerta){
return manager.merge(alerta);
}
public List<Alerta> findAll(){
TypedQuery<Alerta> q = manager.createQuery("select a from Alerta a",Alerta.class);
List<Alerta> alertas = q.getResultList();
for(Alerta a : alertas){
Ente ente = enteFacade.findByPrimaryKey(a.getEnteId());
a.setEnte(ente);
}
return alertas;
}
public List<Alerta> findAlertas(Integer enteId){
TypedQuery<Alerta> q = manager.createQuery("select a from Alerta a where a.enteId =:id and a.dataPublicacao is not null",Alerta.class);
q.setParameter("id", enteId);
List<Alerta> alertas = q.getResultList();
for(Alerta a : alertas){
Ente ente = enteFacade.findByPrimaryKey(a.getEnteId());
a.setEnte(ente);
}
return alertas;
}
public boolean countAlertasNaoLidos(Integer enteId){
Query q = manager.createQuery("select count (a) from Alerta a where a.enteId =:id and a.dataAbertura is null");
q.setParameter("id", enteId);
Long count = (Long) q.getSingleResult();
return count > 0 ? true : false;
}
public void remover(Integer id){
Alerta a = manager.find(Alerta.class,id);
if(a.isPublicado()){
throw new RuntimeException("Alertas já publicados não podem ser excluidos");
}
manager.remove(a);
}
public void abrir(Alerta alerta, Integer responsavelId){
Alerta a = find(alerta.getAlertaId());
a.abrir(responsavelId);
manager.merge(a);
}
}