Dúvida quanto a onde colocar um método

Boa tarde pessoas,

Vou resumir, pra não dar voltas.

Tenho um sistema que faz controle de relatórios que transitam pela empresa em que trabalho. O único propósito desse sistema é:

Os usuários recebem e enviam os relatórios entre os setores da empresa, e fica armazenada um histórico de toda movimentação.

Então, tenho basicamente três classes: Usuario, Relatorio e Setor.

Em Usuario ficam as informações do mesmo:

public class Usuario { private String nome; private String login; private Setor setor; //etc, etc }

public class Relatorio { private Date dataEmissao; private Setor setorAtual; }

public class Setor { private int codigo; private String nome; }

Tenho também minhas classes DAO - que não acho necessário mostrar aqui - e tô desenvolvendo utilizando DDD.
Agora a dúvida: eu tenho uma movimentação de relatórios de um setor a outro. Primeiramente tive a idéia mais simples: colocar o método movimentarRelatorio na classe Relatorio.
Mas ontem vi um post de um usuário em outro tópico ontem que me fez ver a coisa de outra forma: um (ou mais) relatório(s) são movimentados entre setores, e a partir de um Usuario.

Então tenho as seguintes opções, quanto a onde fica o método movimentarRelatorio:

1 - Na classe Relatorio. Mas acho muito estranho, pois um relatorio não se movimenta.
2 - Na classe Usuario, já que é uma operação que o usuário realiza. Também há o fato de que um relatório tem um Setor origem e um Setor destino, tornando, no meu ponto de vista, essa opção a mais correta.

O que vocês acham? Opção 1 ou 2? E porque?

Muito obrigado desde já, forte abraço!

Caso esteja mal explicado, é só falar!

Você tem aquela famosa dúvida:

Temos 3 objetos, Usuario, Relatorio e Setor.

Em português, a movimentação de relatórios tem um sujeito (Usuario), um objeto (Relatorio) e dois lugares (Setor 1 e Setor 2).

Ou seja:

Usuário João movimenta o relatório de Vendas do setor de Alimentos para o setor de Vestuário.

Mas se seu modelo for muito anêmico, a classe Usuário não tem praticamente nenhum método.

Então você criaria uma outra classe, que é a que realmente efetuaria as ações. Só para dar um nome bonitinho, vamos chamar essa classe de Ator.

Pensando em orientação para objetos, você tem a dúvida se você faz algo como:

Mandar a mensagem movimentar-Relatorio para usuário João com parâmetros relatório Vendas, setor Alimentos, setor Vestuario

Ou

Mandar a mensagem movimentar-Relatorio para Ator X com parãmetros usuário João, relatório Vendas, setor Alimentos, setor Vestuario

entanglement,

É exatamente isso! Porém, tô tentando fazer um modelo mais rico, o código que postei é apenas de exemplo.

Qual das duas opções você recomenda, levando em questão exatamente esse problema de objetos anêmicos.

Reli e fiquei na dúvida: o que seria o Ator x? Um tipo de um service? Se a resposta for sim, não é esta a segunda opção. A segunda opção seria na classe Relatorio ter o método movimentarRelatorio().

Apenas ressaltando que tô evitando modelo anêmico, usando DDD. Ou seja: o método movimentarRelatorio fica na própria classe Relatorio ou na classe Usuario - essa última opção é a que me parece mais correta.

Chamo “Ator” um Service mesmo. É que estava sem imaginação na hora :slight_smile:

Eu consigo ver de algumas maneiras.
Usuario pode sim “movimentarRelatorio”, recebendo como argumentos o relatorio, setorOrigem e setorDestino.
Porém, também podemos ter em Setor os métodos enviar e receber.

public void enviar(Relatorio relatorio, Setor destino){}
public void receber(Relatorio relatorio, Setor origem){}

E fazer isso de forma direta, não?

Ótima solução, drsmachado!

Então você concorda comigo que o método movimentarRelatorio não deveria de forma alguma ficar na classe Relatorio?

Muito obrigado! Abraços!

[quote=$ERVER]Ótima solução, drsmachado!

Então você concorda comigo que o método movimentarRelatorio não deveria de forma alguma ficar na classe Relatorio?

Muito obrigado! Abraços![/quote]
Exato.
Relatórios não tem a capacidade de sair do departamento A e ir até o departamento B sem que alguma força aja (terceira pessoa do singular do presente do indicativo do verbo agir, ele/ela aja) sobre ele.

hehe … Entendi.

Então, não quero usar service pra isso, quero deixar esse método dentro de uma dessas classes de domínio: Relatorio, Usuario ou Setor. Pelo que o drsmachado citou, eu ficaria entre Usuario ou Setor. E você, o que acha?

[quote]Exato.
Relatórios não tem a capacidade de sair do departamento A e ir até o departamento B sem que alguma força aja (terceira pessoa do singular do presente do indicativo do verbo agir, ele/ela aja) sobre ele.[/quote]

Agora fico muito mais tranquilo! Muito obrigado por sempre estar me ajudando, amigo! Eu tenho apenas mais um dúvida quanto a esse assunto, vou postar daqui a pouco, se puder ajudar quando estiver disponível, agradeço muito!

Um grande abraço, até logo!

Agora a grande dúvida:

[code]public class Usuario {

private String nome;
private String login;
//restante

public Usuario(String nome, String login) {
//setando os atributos aqui
}

public void encaminharRelatorio(Relatorio relatorio, Setor setorOrigem, Setor setorDestino, Date dataMovimentacao) {

}

}[/code]

Notem que, como a classe Usuario não tem qualquer atributo relacionado a relatório - a lista de relatórios fica na classe Setor, já que cada Usuario pertence a um Setor - me parece que não preciso desse método aqui, ficando apenas no DAO - o que jogaria a lógica no DAO, o que acho péssimo. Alguma solução pra isso?

Só pra deixar claro, não estou pedindo pra ninguem fazer trabalho em meu lugar, quero apenas idéias, já que sou novo em Java, e fiz apenas dois projetos anteriores apenas com Servlets e JSP. Mas estou com muitas dúvidas sobre como utilizar DDD.

Abraços!

O máximo que eu conseguiria seria setar os valores, mas seriam perdidos, pois o método retorna void.

Tô começando a achar que mesmo aplicando DDD não preciso desse método nos domínios, pois a única coisa que o método faria seriam:

salvar a movimentação no banco de dados e gerar um pdf.

Que acham?

[quote=$ERVER]Tô começando a achar que mesmo aplicando DDD não preciso desse método nos domínios, pois a única coisa que o método faria seriam:

salvar a movimentação no banco de dados e gerar um pdf.

Que acham?[/quote]

Concordo. A lógica é tão simples que não é necessário aplicar DDD, matendo assim o KISS principle.

Olá natanaelv,

Primeiramente, muito obrigado por ajudar!

Então, tô chegando a essa conclusão.

Mas estranho é que a OO deixa uns buracos em alguns casos, parece. Repare bem que a operação de encaminhar um relatório pertence ao usuário, mas pode ficar de fora classe Usuario.

Quem tiver uma opinião contrária é só dizer. Abraços!

[quote=$ERVER]Olá natanaelv,

Primeiramente, muito obrigado por ajudar!

Então, tô chegando a essa conclusão.

Mas estranho é que a OO deixa uns buracos em alguns casos, parece. Repare bem que a operação de encaminhar um relatório pertence ao usuário, mas pode ficar de fora classe Usuario.

Quem tiver uma opinião contrária é só dizer. Abraços![/quote]
Na verdade, não é bem a OO que está deixando o buraco. Mas a forma que você escolheu empregar a OO.
Embora modelos anêmicos sejam coisas ultrapassadas, nele você teria um Service que seria o responsável por fazê-lo.
Se optasse por aplicar o pattern Façade, teria um Façade encobrindo a lógica, isolando-a da camada de apresentação, sem envolver um método no bean/pojo para isso.
Como você está trabalhando com o DDD, você assume que o método responsável por mover um documento deve estar associado a uma das classes que está no modelo.
Mas, note que você vai precisar determinar alguma classe para que esta ação (mover o documento do setor a para o setor b) seja realizada.
Se formos analisar as responsabilidades no mundo real, quem move o documento de a para b é uma pessoa. O próprio documento não faz isso sozinho, tampouco um setor envia e outro recebe sozinho.
Ok, mas você não vai criar uma classe “Continuo” ou “OfficeBoy” apenas para mover o documento de um setor a outro. Você precisa de algo mais simples.
Quando eu, em outra resposta anterior, disse que poderia colocar os métodos enviar e receber no próprio setor, foi sob a ótica de que você pode “enviar” o documento gravando-o em um diretório, banco de dados, fila ou o que seja e depois lê-lo no método “receber”. Isso daria mais dinâmica ao processo, afinal, não é por que o office boy entregou os malotes que o relatório será lido imediatamente. Ele será lido quando for a hora.
Claro, esta é uma visão externa, não conheço os pormenores nem as regras que ditam como tua aplicação deve ser criada.

Então drsmachado, não acho ultrapassado, acho que é uma má prática. Segundo o próprio Fowler, ele não entende porque começaram a usar isso, como está no link ai pra trás.

No caso, seria apenas a movimentação lógica - informar ao sistema que o relatório irá ser movimento de a para b - e não o momento que o relatório sai ou entra fisicamente em um setor.

Gostei da solução do drsmachado.

Criar uma classe responsável pela movimentação de relatórios deixa o design mais coeso.
O usuário acaba existindo somente pra fins de autenticação e autorização, e o “EnviadorDeRelatorios” se preocupa apenas com essa movimentação.

falows t+