Primeiro Projeto OO pra valer!

Pessoal, gostaria que dessem seus pitacos nesta modelagem que eu fiz. O objetivo é abrir uma aula no sistema, informando quem está presente e quem faltou, mantendo assim o registro das aulas (andamento da turma) e de frequência.

Não ficarei chateado com críticas, pois estou migrando ainda da programação procedural para a O.O. Quero saber mesmo se há algo errado, porque pretendo implementar as outras regras de negócio de maneira semelhante, então é melhor definir uma arquitetura correta desde já.

A minha principal dúvida é sobre a maneira de criar um novo objeto Aula. Do jeito que está, ele é acoplado com os repositórios de aulas e frequência. A mensagem “new Aula(presencas)” não significa necessariamente instanciar direto com new, eu preferia de obter de alguma forma a aula com os repositórios já injetados. Não queria que o container (a aplicação é EJB 3.1 com Glassfish) injetasse direto um objeto Aula novinho em folha porque agora eu posso estar criando uma aula, e daqui a pouco alterando essa aula pra colocar presença para algum aluno atrasado.

A minha ideia era criar uma Factory para a aula, e esta sim receberia os repositórios injetados. Desta forma, eu chamaria a Factory somente na situação de registrar uma nova aula, para alterar uma aula existente eu a obteria do repositório de registro de aulas.

Como diria Mr. Sinhozinho Malta: “tô certo ou tô errado???”


MarkKnopfler, na minha opinião, antes de discutir o diagrama de sequencias deveria ser discutido o diagrama de classes. A classe Aula chamou minha atenção, acho que não entendi bem a relação desta classe com as outras. Qual o propósito dela?

flws

Fala Fantomas, blz???

Seguinte, eu acho o diagrama de sequência ótimo para modelar, nele eu vejo que objetos estão interagindo e descubro dependências de maneira mais natural.

A intenção da classe Aula é não somente guardar os dados de uma aula (como o conteúdo ministrado, observações, uma lista de alunos presentes e etc.) mas também colocar nela a regra de negócio relativa ao registro de uma aula. Não sei se estou fazendo certo, mas quero evitar modelo anêmico. Eu acho que deveria ter especificado o seguinte:

“Registrar uma aula significa indicar que aquela turma fez aquela aula, anotar todas as ocorrências relevantes, o conteúdo ministrado (para comparar com o cronograma padrão) e registrar a chamada no registro de frequência.”

Ou seja, se a “aula dada” fosse só um bolo associando uma turma, uma “aula prevista” no cronograma e um punhado de “alunos” presentes, essa classe até seria inútil. Mas essa associação tem dados: a “aula dada” tem data, observações, ocorrências, conteúdo efetivamente ministrado (se foi possível fazer conforme o padrão ou teve algo diferente, às vezes o “diferente” é bem-vindo!), etc.

Talvez eu devesse diferenciar as entidades com os nomes AulaDada e AulaPrevista :wink:

O que acha? Logo vou ter mais perguntas e abrir outros posts, paciência com este iniciante em OO e Design Patterns :wink:

Acho que agora entendi um pouco mais.

A principio as pessoas se sentem bastante atraídas pelo diagrama de sequencia, talvez seja porque se parece com alguns aspectos do paradigma estruturado ou algo assim.

Porem o treco é muito mais amplo e muito mais profundo que isso; existe um processo de análise e design OO para se chegar em um artefato executável. Ao falar disso lembramos dos requisitos, casos de uso, diagrama de classes e etc… relacionados ao aspecto estático. Existem ainda os outros vários diagramas que representam o aspecto dinâmico, o diagrama de sequencia é um exemplo deles.

É necessário fazer tudo isso? Na minha opinião não, porem para excluir ou incluir estas idéias é necessário estar seguro do que esta fazendo. Por exemplo, como fiquei na dúvida sobre uma das entidades logo de cara senti falta do diagrama de classes. Este diagrama iria me mostrar o que é e como esta entidade se relaciona com as outras entidades.

Se vc construir um modelo ruim vc irá invariavelmente acabar construindo entidades anêmicas ou classes com muitas responsabilidades (classes GOD) que tentam fazer tudo, isto sem falar nos algoritmos que serão afetados seriamente.

Enfim…falei tudo isto porque o titulo do tópico é “…projeto OO…”.

A sua explicação sobre a classe Aula me fez lembrar do famoso diário de classe que o professor deveria preencher e não exatamente de uma aula.

flws.

Bem, o famoso “diário de classe” está ali, na minha classe RegistroFrequencia.
Acontece que toda Aula tem que ter a chamada para todos os Alunos. É a regra de funcionamento da Aula.
No caso, o método que seria “god” é só o seguinte:

   /**
    * Lógica de negócio de registro de aula:
    * - registra a aula no registro de aulas (andamento da turma)
    * - registra as presenças no registro de frequência
    */
   public void registra() {
      registroAulas.registra(this);
      registroFrequencia.registra(presencas);
   }

Ou seja, a classe Aula não está nem fazendo muita coisa, está mais delegando. Ela só define o que é necessário para um registro de aula estar completo, mas deixa a tarefa do “diario de classe” para o objeto da classe RegistroFrequencia, que é o verdadeiro diário.

Eu só achei que, como toda aula tem que ter o registro da frequência (regra de negócio), então a classe Aula deveria pelo menos coordenar essa atividade. O registro de frequência não existe de maneira isolada da Aula.

Aí que está, estou me justificando muito, mas se há algum problema com essa modelagem, eu gostaria mesmo de saber. Logo o diagrama de classes está chegando :wink:

Diagrama de classes “fresquinho” para quem quiser avaliar. Está focado no relacionamento entre as entidades. Abstraí os repositórios e as operações de negócios que as classes virão a ter posteriormente, porque para esse caso de uso em específico só interessa a operação “registrar aula dada”.

Prometo que não vou pedir para modelarem o sistema inteiro para mim, é só para dar uns pitacos onde pode melhorar. :wink:


Olá Mark,

bom, IMHO acho que você está cometendo um equívoco bastante comum quando se tenta abandonar o chamado modelo anêmico. É interessante sim que as entidades tenham regras de negócio, que não sejam apenas “pacotes” de dados , como os velhos DTOs. Por outro lado, penso que regras de negócio devam ser expressas em termos de objetos de negócio. Sendo assim, não faria sentido que o objeto Aula possua referências para um repositório ou algum outro objeto que faça parte da infra-estrutura da aplicação entendeu ? Por exemplo, se faz parte do modelo que um objeto Turma seja composto de Alunos, ao “sair” do repositório o objeto já deve estar completo, não havendo necessido de acessar um segundo repositório, mesmo que quem faça esse acesso seja a própria classe Turma. Tanto é assim que você já está tendo dificuldade em construir o objeto Aula, precisando injetar repositórios, etc.

Por fim, tome cuidado com a “febre dos padrões”. Nem sempre é interessante aplicar padrões de antemão. Muitas vezes vale mais a pena você construir a aplicação e posteriormente refatorar para padrões …
Outra dica: nem sempre desacoplar tudo e injetar tudo é bom, em um determinado momento o new será necessário, e nem sempre compensa ficar postergando a criação de um objeto.

RMendes, thanks pela dica! É basicamente isso que eu estava necessitando. Vou colocar essa lógica da aula em um lugar mais adequado. Poderia ser no próprio RegistroAulas, não poderia? O RegistroAulas “registra aulas” (ui!), pronto. Tão coeso que ficou até óbvio, PMEA (Pelo Menos Eu Achei). E continua sendo um repositório de aulas, só que quando eu mandar ele fazer registro.salvar(aula), ele executa a lógica de negócio específica do registro de aulas. E ficaria responsável por chamar o RegistroFrequencia para fazer a parte dele, PMEA.

Tô certo ou tô errado??? :wink:

[quote=MarkKnopfler]RMendes, thanks pela dica! É basicamente isso que eu estava necessitando. Vou colocar essa lógica da aula em um lugar mais adequado. Poderia ser no próprio RegistroAulas, não poderia? O RegistroAulas “registra aulas” (ui!), pronto. Tão coeso que ficou até óbvio, PMEA (Pelo Menos Eu Achei). E continua sendo um repositório de aulas, só que quando eu mandar ele fazer registro.salvar(aula), ele executa a lógica de negócio específica do registro de aulas. E ficaria responsável por chamar o RegistroFrequencia para fazer a parte dele, PMEA.

Tô certo ou tô errado??? :wink:
[/quote]

Quase isso, basicamente, o ponto que eu quero chegar é que:

regras de negócio != persistência

Às vezes, quando trabalhamos com cadastros simples, por exemplo, um cadastro de pessoas, praticamente não se tem regras de negócio, e ai o sistema fica com cara de modelo anêmico mesmo. Mas seria diferente por exemplo, da entrada de uma nota, que ai sim você precisaria de objetos mais inteligentes para calcular totais, descontos, impostos, etc.

Enfim, confesso que às vezes é difícil fazer essa separação, mas vale a pena fazer um esforço.

[quote=rmendes08]Olá Mark,

bom, IMHO acho que você está cometendo um equívoco bastante comum quando se tenta abandonar o chamado modelo anêmico. É interessante sim que as entidades tenham regras de negócio, que não sejam apenas “pacotes” de dados , como os velhos DTOs. Por outro lado, penso que regras de negócio devam ser expressas em termos de objetos de negócio. Sendo assim, não faria sentido que o objeto Aula possua referências para um repositório ou algum outro objeto que faça parte da infra-estrutura da aplicação entendeu ? Por exemplo, se faz parte do modelo que um objeto Turma seja composto de Alunos, ao “sair” do repositório o objeto já deve estar completo, não havendo necessido de acessar um segundo repositório, mesmo que quem faça esse acesso seja a própria classe Turma. Tanto é assim que você já está tendo dificuldade em construir o objeto Aula, precisando injetar repositórios, etc.

Por fim, tome cuidado com a “febre dos padrões”. Nem sempre é interessante aplicar padrões de antemão. Muitas vezes vale mais a pena você construir a aplicação e posteriormente refatorar para padrões …
Outra dica: nem sempre desacoplar tudo e injetar tudo é bom, em um determinado momento o new será necessário, e nem sempre compensa ficar postergando a criação de um objeto. [/quote]

Acabei de chegar e não lí o post todo ainda. Mas queria fazer uma correção: a intenção do Repositorio (DDD) é, sim, fazer parte da camada de negócios. Essa é a diferença do Repositório para um DAO: o Repositorio faz parte da camada de negócios (portanto, pode possuir lógica) e o DAO, sim, é infraestrutura. Nesse sentido, não há mal nenhum em injetar o Repositorio em um objeto de negócio, ao contrário - é encorajado, seguindo os ideias de IoC e DI.

[]'s

Então, é exatamente isso que estou fazendo.
O RegistroAula é um repositório E um objeto de negócio (é assim que deve ser). E como o registro da aula está atrelado ao registro da frequência (essa é a regra do negócio), nada mais justo do que esse repositório fazer referência ao outro, o RegistroFrequencia.
Mas os dois são repositórios separados, o RegistroFrequencia vai ter a pesquisa de frequência por Aluno, por exemplo.

[code]package br.com.gamecursos.modelo.repositorio;

import br.com.gamecursos.miocc.annotations.*;
import br.com.gamecursos.modelo.AulaDada;
import br.com.gamecursos.domainstore.DsAula;

@Named @Singleton
public class RegistroAulas extends RepositorioPadrao {

private RegistroFrequencia registroFrequencia;

@Inject
public RegistroAulas(DsAula dsAula, RegistroFrequencia registroFrequencia) {
super(dsAula);
this.registroFrequencia = registroFrequencia;
}

/**
* Lógica de negócio de registro de aula:
* - registra a aula no registro de aulas (andamento da turma)
* - registra as presenças no registro de frequência
*/
@Override
public void salvar(AulaDada aula) {
getArmazenamento().salvar(aula);
registroFrequencia.registra( aula.getPresencas() );
}

}[/code]