| Autor |
Mensagem |
|
|
sergiotaborda wrote:eu entendo, mas não acho certo. quem vai por e tirar o carrinho da sessão tem que ser um objeto com acesso à sessão . O mais obvio é o action, mas vc pode criar um terceiro objecto que encapsula o acesso à sessão ( mas acho que isso é over kill)
Entendi seu ponto de vista. A mais fácil serializar o objeto CarrinhoCompra todo e trabalhar a serialização/deserialização na Action mesmo para evitar problemas e over kill.
sergiotaborda wrote:E qual é o problema disso ?
Os pedidos sim têm que ser acessados em qualquer lugar. São classes publicas, não são ?
No meu entendimento, dando ao pedido a possibilidade de "ter vida" sozinho, a aplicação perderia o sentido. Eu pensei na Cliente ¹<composicao>----* Pedido porque em teoria só existe Pedidos se houver clientes. Mas eu estou vendo que não é preciso seguir isto tão ao pé-da-letra [..]
Então, tendo em vista as dicas que venho recebendo, vamos tentar outro modelo:
(Agora com quantificadores =])
Conforme me sugeriu, coloquei um Serviço para o pedido, assim, eu consigo trabalhar com Pedido em mais de um lugar (como você mesmo disse mais acima). O Cliente talvez também tenha seu Serviço. O Carrinho tem lá suas relações com Cliente e Produto(s) normalmente.
A única coisa que não fiz nesse diagrama foi a relação Pedido - Cliente. Eu penso que seria ideal ter a relação: Cliente.getPedidos() retornar uma collection de Pedido. Isso é trabalho do Repositório, penso. Ele que ao buscar a collection de clientes traria (caso eu pedisse) os pedidos desses clientes também, correto ?
sergiotaborda wrote:Poderia.
Poderia ser só um repositorio tb. Depende do que é o seu objeto de report.
Hum. Se o meu report fosse útil para vários fins, seria interessante encapsular isto num Service, do contrário poderia manter só o Repositório, seria isto ?
Agradeço a ajuda!
|
 |
|
|
sergiotaborda wrote:Ok, mas use uma coleção. Não use arrays!
Sem dúvidas. Apenas me expressei de forma errada =(
sergiotaborda wrote:A ideia está certa mas o digrama errado. O diamante preto é do lado do pedido, não do cliente. Além disso faltam quantificadores em todo o modelo.
Sério mesmo que o diamante é do lado oposto ? hahahaha... eu jurava que estava certo. Se for assim acho que tá tudo invertido então !
Ao menos a minha idéia do "Pedido não poder andar sozinho" faz sentido.
sergiotaborda wrote:acho que vc eastá viajando... O objecto CarrinhoDeCompras é que existe na sessão. O objecto lá dentro não precisa persistir nada em lugar nenhum.
Mas se eu persistir o objeto CarrinhoCompras em sessão, quem irá controlar esta sessão ? Digo, trazer o CarrinhoCompras devolta para por exemplo, adicionar mais um item à cesta ? Eu estava pensando em fazer os atributos deste carrinho serem salvos em sessão e o próprio CarrinhoCompras controlar essas sessões, entende ?
sergiotaborda wrote:A sua frase equivale a "ninguem mais esperto para controlar uma cirurgia ao coração que o proprio dono do coração"
Isso está errado. A compra/venda é uma outra entidade do sistema. Porque o pedido seria capaz ou responsável de manipular essa entidade ? A manipulação conjunta de 2 ou mais entidades indica a necessidade de um serviço ( que já tinha sido indicado na primeira duvida)
Realmente, pensando dessa forma fica estranho mesmo.
Pensando com calma agora, eu vejo que o Cliente poderia finalizar esta compra. Entretanto, seria mesmo estranho um Cliente.finalizarCompra(). Então, penso que seria interessante ter uma classe que ficasse responsável pela entidade Pedido e essa classe, receberia a coleção de produtos e o cliente para finalizar a compra.
Algo como:
sergiotaborda wrote:É como não ver a vantagem de escover os dentes todos os dias, mas ao final de vários anos vc entende a vantagem.
use o serviço. Vc mesmo chegou na conclusão que precisa dele, mas está resistindo. É muito mais simples que ficam gambiarrando o sistema.
Não sou contra ele. Apenas tenho receio de colocar o Serviço em Pedido e acabar fazendo ele (Pedido) ficar "desacoplado" do Cliente. Em outras palavras, criando o ServiçoPedido eu não estaria fazendo meu Pedido ser acessível por qualquer um em qualquer parte da aplicação ?
Porque se não for algo que vá deixar o Pedido viajando sem rumo pela aplicação, eu poderia criar o ServiçoPedido e centralizar as tarefas nele. Neste caso, o Cliente.getPedidosFinalizados() iria solicitar ao ServicoPedido.listaFinalizados(), ou não ?!
sergiotaborda wrote:Sim. qualquer coisa que seja logica de negocio/dominio que aconteça numa action é um pecado.
Vc cria uma outra classe. Vc passa a ela os parametros e ela gera o report. A action recebe esse report e mostra. Só isso.
Entendido.
"outra classe" = Serviço ?
Adolfo Rodrigues wrote:TDD ajuda muito na construção de um design limpo e elegante. Acho que você deveria considerar esta alternativa...
Desenvolvimento Orientado à testes eu irei aprender um dia. Por hora estou limitando-se ao design OO mesmo para tentar entender como as coisas funcionam. Acho que eu parar para pegar sobre TDD iria dar um nó ainda maior. Apenas "acho" porque nunca li muito sobre TDD =( Ainda estou começando a ler sobre DDD - consegui comprar o Livro do Eric Evans \o/.
Mas irei guardar a dica ! Isso acaba me deixando mais interessado sobre TDD e Agile =)
Abraço a todos !
|
 |
|
|
Salve turma !
Estou criando um modelo aqui porém surgiram algumas dúvidas que gostaria de tirar com os senhores.
Abaixo tem o diagrama de classes:
A idéia seria realizar as tarefas:
- Através da classe Cliente eu poderia descobrir os pedidos realizados pelo tal Cliente usando o Clientes.getPedidos(). Esse cara me retornaria um array contendo os Pedido(s).
Dúvida: eu coloquei o Pedido como composição de Clientes, com isso eu não teria um Pedido andando sozinho pelo sistema. (tem até uma certa lógica, certo ?) Porém, se eu precisar de um relatório de todos Pedidos pagos já era, pois os pedidos estão atrelados a cada Cliente.
Pensei em usar algo como um Serviço para resgatar esses pedidos, mas eu não vi muita "relação" entre o Serviço Pedido "perdido" na aplicação.
- A classe CarrinhoCompras irá conter os Produto(s) adicionados à cesta até o momento. Qualquer um pode adicionar, cliente ou não. Porém, para utilizar o método CarrinhoCompra.registraCompra() o usuário precisa estar autenticado, para que o CarrinhoCompra delegue a tarefa de finalizar o pedido à classe Pedido (ao meu ver tem sentido essa relação)
Dúvida: no CarrinhoCompras.adiciona() eu irei persistir o produto em sessão. Neste caso, o próprio carrinho persiste isto, tipo um ActiveRecord. Eu acho que neste caso, o AR cairia bem, o que acham ?
Dúvida2: a delegação de CarrinhoCompra.registraCompra() para Pedido.registraCompra(carrinho) penso ter sentido, até porque ninguém mais esperto para controlar o Pedido do que o próprio pedido e em contra partida, o CarrinhoCompra.registraCompra() após delegar a tarefa e recebendo um "sinal" positivo, poderia por exemplo limpar o carrinho. O que acham ? Eu talvez pudesse chamar diretamente o Pedido.registraCompra() na Action/Controladora. Daí a dúvida.
- A classe Produto se relaciona usando agregação com Pedido e com CarrinhoCompra. Aqui não tem problemas.
No geral, penso que para o Cliente seria interessante ter um Serviço enquanto que Pedido e CarrinhoCompras seriam persistidos usando ActiveRecord e acessados diretamente na minha Action.
Aqui no GUJ já vi gente defendendo o uso de Services sempre que for possível. Só que nesse meu raciocinio - limitado ainda X) - eu não vejo porquê acessar Pedido via Serviço (ele existir fora do Cliente).
E no caso de Relatórios de Pedidos eu poderia chamar o Repositório do Pedido diretamente na Action. Ou seria isto "um pecado" ?
O que vocês pensam sobre tudo isto ?
Abraços!
|
 |
|
|
sergiotaborda wrote:
hlegius wrote:
repare que result.count() é mais eficiente que fazer o select todo
vc só irá fazer o select em list() se souber que ha alguma coisa para ler. ( isto é um exemplo, no codigo real vc faz o for e pronto)
Outra forma de usar
Ao que entendi, esse findActive() não iria fazer chamada alguma na SQLDao. Apenas montaria o critério de busca. Daí, com o critério pronto, o list() retornaria todos, o count() o SELECT COUNT, o isEmpty() verificaria se não retornou nada e etc... correto ou entendi errado ?
sergiotaborda wrote:O Hibernate funciona exactamente assim porque é uma implementação de DomainStore. Usar QueryObject com DomainStore ou DAO é natural.
Mas isso não significa que vc tem que espalhar as suas Criteria pelos seus Actions. Isso o hibernate não o obriga a fazer.
Vc pode criar um repositorio que chama o hibernate tranqüilamente. (aliás vc deve fazer isso se gosta de codigo mantenivel )
O repositorio que use hibernate é responsável por montar os criteria com base nos parametros e passar ao hibernate.
Implementar um QueryResult baseado no query do hibernate tb é simples, já que o Criteria já implementa os vários métodos diferentes ( ele já otimiza as chamadas da forma que estavamos falando).
Legal. Muitos exemplos que eu vi pela rede, trabalha com Active Records. A implementação com Repositório no caso, seria bem similar a implementação com DAO's comuns, né ? Digo, apenas precisaria mudar, onde eu chamo as daos, eu precisaria transportar os dados para o Hibernate.
sergiotaborda wrote:Exatamente. esse é o papel principal do repositório. Ele tem outras vantagens, mas todas derivam dai.
Ufa! Acho que estou começando a sacar a idéia =)
sergiotaborda wrote:vc está simplesmente seguindo o Principio de Separação de Responsabildiade, em particular Encapsulamento, que é uma prática comum do OO.
O que por si só é excelente.
Abraço e obrigado pela força! Realmente ajudou muito !
|
 |
|
|
sergiotaborda wrote:Ah! agora entendi o seu ponto. Vc acha que isso são pesquisas especializadas. Não. São 3 métodos fazendo a mesma pesquisa e retornando informações diferentes dela. Em um projeto onde vc tivesse a pesquisa "usuáriosAtivos" vc teria findUsuariosAtivos : List getFirstusuarioAtivo : usuario countUsuariosAtivos : int Para cada pesquisa vc teria 3 metodos. Para N pesqusias vc teria 3N métodos. Com o outro modelo vc agrupa os métodos em um objeto de retorno. Então vc tem N pesquisas e N métodos. muito mais simples , não ?
Pera lá então: no seu exemplo temos somente 1 tipo de busca. O que varia são os tipos de retorno. Um Retorna a Collection outro a entidade fora da collection e o outro um número (inteiro) possívelmente. 3 métodos, 1 tipo de busca. Com isto realmente teriamos muito código duplicado e o problema da manutenabilidade como você disse. Porém, o "outro modelo" que você citou eu não entendi bem como poderia especificar ao método do Repositório que eu quero um getFirstusuarioAtivo ou que eu quero um countUsuariosAtivos.
Veja, no seu exemplo eu usaria o que para dizer ao findActive() que eu quero chamar o find() que me retornará um TOP 1 por exemplo ?
sergiotaborda wrote:Não. Nada disso. O QueryObject não faz nada. Ele é apenas um conjunto de dados. Um criteria do hibernate é um QueryObject. O String SQL passado no statement é um QueryObject.
Legal, até aqui eu entendi. No meu pensamento o QueryObject mandava a DAO passear, mas depois da sua explicação eu percebi que ele manda o Repositório passear. Ao que entendi, o Repositório está para nos servir com Objetos da persistência e agora também evitar um monte de Criteria espalhadas pelas Actions. Se eu entendi corretamente, uma implementação possível seria: Minha Action chamaria o Repositório - nesse caso acho que não precisaria de Serviço: Dessa forma eu não exibiria a implementação dos critérios de busca, evitaria um monte de Criterio nas Actions. Eu apenas não entendi como poderia fazer meu Repositório buscar de formas diferentes uma mesma informação, assumindo o exemplo acima... Ao que entendi, minha DAO é melhor aproveitada, porém eu teria 3n Métodos no Repositório para n pesquisas especializadas. Justamente o que não é ideal para a manutenabilidade. =( Pois se eu precisasse fazer uma busca por inativos, eu teria que adicionar no repositório mais 3 métodos. findInativos(); listInativos(); countInativos(); A DAO ficaria com os 3 de sempre, penso.
sergiotaborda wrote:Agora, o QueryObject tende a ser mais complexo. A ideia é vc poder pedir aquelas 4 informações de forma combinada algo assim QueryObject q = QueryObject.for(Product.class). where("name").eq(name). and("active").isTrue(). and("selled").in(intervalo) Ai vc passa para o método find() e pronto. Bácisamente o seu repositorio começa a ter um só método. Só que isso destroi o repositorio. O objectivo do repositorio é manter e conter a contrução do QueryObject
Entendi. A idéia do QueryObject é não ter aquela chuva de pesquisa no Repositório, logo, isso acaba com a utilidade do mesmo. Entretanto, teremos QueryObject esparramadas em todas Actions. Se precisar alterar algo algum dia, ferrou ! Mas vem cá, o hibernate não trabalha exatamente assim ?
sergiotaborda wrote:aposto que isso não era um repositorio e sim um DAO. Pela simples razão que os repositorios não recebem QueryObject complexos ( como já expliquei ) e Criteria é um objeto complexo. Isso que vc descreveu é o que o um DAO ou um DomainStore faria.
Sim, era um repositório! Veja na imagem: http://helio.hlegius.pro.br/imagens/oop/repository_de_acordo_com_livro.jpg
sergiotaborda wrote:A Criteria que foi enviado ao objeto veio de onde ?
Veio da Action.
sergiotaborda wrote:Foi montada por quem ?
Pela Action.
sergiotaborda wrote:Quem escolheu os parametros para ela ?
Possivelmente poderia ter sido o usuário utilizando-se da interface selecionou os campos a serem filtrados, porém, novamente a Action que tratou essa informação e criou a criteria.
sergiotaborda wrote:Em um sistema como Repositorio , seria o repositorios a fazer isso e a invocar esse objeto que vc descreveu. em um sistema sem Repositorio , básicamente qualquer classe pode invocar o DAO, logo a construção do Criteria está espalhada pelo sistema inteiro. E isso é um problema. Esse é o problema que o repositorio tenta resolver. ele é um cara "acima" do DAO que sabe como criar Criterias , invocar o DAO, e tratar o resultado.
Isso reforça a idéia: repositório ajuda na manutenção das instruções da Dao.
pcalcado wrote:Um Repositório é uma ilusão de coleção de objetos, não alguém que responde à queries. Se você quer saber quantos objetos estão dentro de um repositório provavelmente para o cliente isto é apenas um atributo deste, não o resultado de uma pesquisa.
Isso ! No caso, aliás, no meu caso, geralmente eu preciso de um "count()" para retornar informações para paginações ou/e exibir informações adicionais na interface, como por exemplo: "Vendo X registros de um total de 400". Em ambos casos, eu precisaria fazer um find() especializado naquele filtro + um count() para saber quantos são os registros todos (sem filtros). Neste caso Phillip, o que poderia eu fazer ? Implementar o count() no repositório retornando um "Int" ao que entendi, você não é muito a favor, mas eu ainda não consigo ver outra solução...
pcalcado wrote:E antes de partir para QueryObject, algo *bem* inra-estrutura e fora de DDD, siga a suestão do Evans e faça a dobradinha Specificaction/Repository
Seguirei sem dúvidas. Até por que, se eu for criar um queryobject e suas criterias é melhor eu usar algo pronto, como hibernate...
pcalcado wrote:Agora se você ainda não leu o livro eu recomendo que o faça antes de tentar qualquer coisa com Domain-Driven Design. Existem muitas fontes de informação completamente distorcidas por aí.
Farei assim que possível. A grande questão é que apenas fora do país tem esse livro disponível, e as lojas nacionais têm um prazo altíssimo para "possível" entrega do mesmo. Isso quebra as pernas =(
|
 |
|
|
sergiotaborda wrote:Um repositorio ideal ( no sentido de ser proximo da ideia ) teria vários métodos de pesquisa, cada um recebendo um objeto com os parametros da pesquisa e retornando um objeto de resultado. (Como exemplo, pense no statement do SQL. Ele recebe um String como parametro e retorna um ResultSet como resposta).
Neste caso, o Repositório "ideal" teria várias pesquisas especializadas. Cada tipo de pesquisa receberia um QueryObject como parametro para podermos filtrar a informação a ser buscada igual você exemplificou, correto ? Ou seja:
sergiotaborda wrote:Do ponto de vista do design é mais correto ter um objeto especifico para ser o seu ResultObject. Este objeto terá uma interface mais simples que List e portanto vai libertá-lo de ter de implementar métodos exotiericos como retainAll().
Ah sim, perfeito. Entendi seu ponto de vista. Implementar algo mais "direto" à implementar algo que me obriga a implementar comportamentos que eu não vou ultilizar.
sergiotaborda wrote:Ou seja, invocar resultObject.count() é mais rápido que invocar resultObject.list().size() porque por detrás dos panos vc não está carregando nenhum objeto realmente.
Aqui é o ponto da dúvida. Meu Repository pode muito bem retornar ao meu Serviço um valor "não-collection/list". Posso muito bem no meu serviço solicitar ao meu repositório que retorne-me o total encontrado, como por exemplo: Isso seria equivalente a eu chamar o find().size() só que economizando uma boa memória, pois por detrás teriamos apenas um SELECT COUNT(1)/TOP 1... Legal, acho que isso desata o nó que esse tópico tinha dado em minha cabeça ! Fico muito grato pela explicação completa que deu. Agora, aqui você comentou sobre a QueryObject. Eu durante esse final de semana consultei alguns livros e li algumas coisas na rede sobre. Ao que pude entender, o QueryObject é o cara que "tira uma DAO" de jogo. Ele quem roda os SQL's e devolve os resultados ao Repositório. Ele trabalha junto ao Criteria que é o cara responsável por criar os critérios de busca. No exemplo que vi no livro, o Repositório do cara recebia uma Criteria como parametro e o Repositório implementava o QueryObject passando a entidade e a criteria por meio de setter injection. A QueryObject dele montava a sentença SQL, buscava os dados e retornava o ResultSet ao repositório que montava a collection e devolvia assim ao serviço. O Repositório dele se comporta de maneira bem similar ao que você explicou aqui na thread. Um list simples e "descompromissado" com métodos que não têm utilidade e o count() dele retorna o integer usando o TOP do SQL. Tal implementação estaria correta ? Agradeço a força ! Abraço!
|
 |
|
|
O repositorio não retorna os objetos de dominio. Ele retorna o resultado da pesquisa. (..)
Se ele retorna os resultados da pesquisa, é correto retornar por ele um "inteiro" contendo o valor da pesquisa do count() correto ?
Agora, para um repositorio que use JDBC vc pode implementar as coisas de forma diferente. count , por exemplo, executaria um select diferente que apenas retorna a contagem de itens sem ter que ler os itens ( é isso que vc quer). isEmpty pode executar o mesmo select e comparar se é zero. find pode limitar a procurar ao primeiro item como um Top 1 (SQL SErver ) ou limit (postgres e outros...)
Entendi. Estive reparando que o Repository serve para buscar dados, trazer list/Collections ... não é necessariamente tarefa dele as outras coisas, como adicionar, atualizar, remover ou até mesmo, trazer um valor inteiro - o count().
Então, essa Query object se parece meio com o Repository no aspécto do list()... ou seja, fiquei meio perdido com isto. Um se comunica com o outro, ou cada um faz um papel diferente e nem se encontram no sistema ?
Procurei um pouco sobre QueryObject, mas não descobri se ele é do lado da infra ou se é pertencente ao domínio... acho que meu cerebro deu um nó =)
Ao que reparei, o pessoal usa junto a Criteria que tudo isso junto acaba sendo o embrião de um ORM tipo hibernate...
Se eu falei só besteira, realmente é porque o nó está bem atado =(
|
 |
|
|
... eu não poder/necessitar criar uma entidade para devolver ao serviço ?
Por exemplo, para retornar um produto pelo "id", ele retornará ao serviço a entidade Produto. Mas e se eu apenas precisar retornar quantos itens foram encontrados (sim, eu uso DAO's e sem ORM). A grosso modo, na DAO teriamos algo como:
Nesse caso, eu apenas receberia um inteiro contendo o total encontrado. Tendo isto em mente, teria sentido passar essa informação ao repositório ?
Na minha opinião, até faz sentido, porque a DAO é um mundo diferente do mundo do Domínio e suas entidades, mas por outro lado, seria apenas um "passa-repassa" entre DAO-Repositório-Serviço até chegar na Controladora/whatever-you-want o valor "10" por exemplo.
O que os senhores acham a respeito ?
Obs: poderia usar um SELECT * e retornar uma coleção de Produto, mas acho que isto iria gastar processamento desnecessário e ao meu ver, ficaria mais 'feio'
Abraços!
|
 |
|
|
Mauricio Linhares wrote:
hlegius wrote:Você citou o possível uso de uma factory method, mas como você mesmo disse, eu precisarei buscar os reagendamentos feitos para gerar relatórios depois, por isso preciso deles separados. Entretanto, poderia eu usar uma façade no RepositórioAgendamento para realizar o Reagendamento (finalizar um agendamento e criar outro), ou será que seria desperdício de tempo ? X)
Não é uma boa idéia fazer o repositório depender de uma fachada do sistema, pior, vai terminar criando um ciclo, repositório depende de fachada que depende de repositório.
huum ! verdade. Só complica, não acaba ajudando muito.
s4nchez,
Eu li sobre o que me sugeriu. Pelo que entendi é recomendado termos um repositório só, mas acho que para rolar isso bem precisaria ter um ORM para fazer a infra de persistência, como nesse meu caso não tenho, ficaria difícil manter um repo apenas. Daí neste caso, teria - acho - que manter um repositório per entity. Foi isso que pude entender da pesquisa que fiz
|
 |
|
|
cmoscoso wrote:Voce parece ter bons argumentos que justificam sua decisao mas ela visa aprimorar um infraestrutura de persistencia que poderia ser preenchida por uma ferramenta de mercado. Se vc vai ter que fazer esse trabalho eu presumo que menor atencao sera dedicada aquilo que gera valor pro cliente.
Pois é ! Estou sentindo na pele isto. Como não tem como fugir, a solução é encontrar a saída mais "viável" para este "problema" de falta de ORM na aplicação X)
Mauricio wrote:O ideal é que o seu repositório faça isso (verifique as entidades relacionadas e salve elas de acordo), pois pode vir a acontecer de um reagendamento ser criado fora desse serviço.
Aparentemente, no seu caso, a única coisa que já não está gravada é o "agendamentoNovo", então seria simples fazer o seu repositório de Reagendamentos delegar para o repositório de Agendamentos a gravação do tal "agendamentoNovo".
A princípio todo reagendamento utilizará o mesmo serviço. Talvez no futuro mude, mas o escopo atual não precisa disto.
Como o cmoscoso citou estou "me matando" com isto pois não tenho uma ferramenta ORM cuidado da persistência, logo, ao que entendi eu poderia sim fazer uma delegação para outro Repositório.
Você citou o possível uso de uma factory method, mas como você mesmo disse, eu precisarei buscar os reagendamentos feitos para gerar relatórios depois, por isso preciso deles separados. Entretanto, poderia eu usar uma façade no RepositórioAgendamento para realizar o Reagendamento (finalizar um agendamento e criar outro), ou será que seria desperdício de tempo ? X)
Abraços!
|
 |
|
|
cmoscoso,
Sim, eu poderia implementar diretamente na DAO, mas eu estava pensando no seguinte: a manutenção. Se eu colocar diretamente na DAO, eu teria código duplicado, pois os comportamentos de adicionar novo agendamento e finalizar um agendamento existem já no serviço Agendamento.
Pensando mais a fundo desta forma (na manutenção), penso que deixar o Serviço Reagendamento delegar a Finalização e Criação dos agendamentos seria uma saída interessante, pois qualquer alteração no meu Agendamento, eu teria apenas um lugar para alterar, e não dois (no caso dos sqls da DAO).
O que acha ?
s4nchez, vou pesquisar sim. Agradeço a dica !
Abraços!
|
 |
|
|
Mauricio,
Meu caso é o seguinte: tenho uma entidade Reagendamento a qual contém dados sobre os reagendamentos efetuados na agenda (domínio: agenda) e em contra partida, eu tenho uma entidade Agendamento que cuida efetivamente dos agendamentos que aparecem na agenda.
Um reagendamento é nada mais do que: uma atividade estava agendada (entidade Agendamento) todas quartas-feiras até uma data X, porém, a partir da data Y ela será todas as quintas, por exemplo.
Como o sistema precisa manter o "passado" dessa agenda intacto em caso de atualizações, eu preciso finalizar o primeiro Agendamento, criar o novo (na quinta à partir da data Y) e a entidade Reagendamento controla as duas entidades Agendamento (a antiga e a nova) além da data Y e quem alterou isto.
Modelei a Reagendamento da seguinte forma:
Reagendamento.agendamento_antigo - que contém o Agendamento antigo
Reagendamento.agendamento_novo - que contém o objeto Agendamento novo
Reagendamento.autor - que contém o objeto Usuario
Reagendamento.data - que contém a data de inicio desse reagendamento
Então, numa ação de reagendamento, a Entidade Reagendamento precisa persistir as informações delas (pois isso será usado depois para relatórios)
e também, cancelar o Agendamento antigo e criar o novo Agendamento
As ações de criar e cancelar os Agendamentos, a própria Service do Agendamento está cuidando tranquilamente. Eu preciso apenas chamá-las para que façam suas partes. (Cancelar e Criar o novo)
E não, não estou usando nada parecido com hibernate. A grosso modo seria um JDBC comum com DAO e etc =/
|
 |
|
|
Olá a todos !
Aqui estou novamente com mais uma dúvida de modelagem X)
Tenho uma classe de Serviço que chama seu repositório para persistir a entidade. Até aí tranquilo. Porém, eu preciso persistir objetos diferentes na mesma ação e fiquei a me perguntar: o Repositório da entidade "principal" (se é que posso falar assim), pode chamar outros Repositórios passando a eles as informações de que eles necessitam para persistirem também ou seria mais interessante eu fazer essas rotinas na classe de Serviço ?
Eu explico o por quê disto: tenho objetos alinhados, ou seja: objetoA.objetoB.propriedade_objetoB o famoso "objeto dentro de objeto". Assim como um objeto Pedido pode trazer um ArrayList de Produtos dentro dele.
A principio eu pensei: ah, repositório fala com repo tranquilamente, porém, essa pattern eu não domino muito ainda, vai saber que não é interessante isto (..)
Agradeço a força !
|
 |
|
|
peczenyj wrote:(..)
Sobre a classe Foto: de a ela um comportamento definido e não fique pensando demais no futuro: quando chegar a hora de refatorar: refatore.
Então no caso, seria fornecer a ela o comportamento especifico para a foto do produto. Se eu precisar de mais tipo de fotos ao longo do projeto (depois em outras fases, pois por hora não preciso) eu volto e refatoro, certo ?
Abraços!
|
 |
|
|
Giulliano wrote:É uma questão de análise. Pra que desperdiçar funcionalidades se a empresa não precisa de controle sobre uma foto.
Imagine num mundo real onde vc ganha R$ 30,00 a hora. E me diz que vai gastar 8 horas criando a tal da Foto e suas implementações onde o que eu te pedi foi controle sobre o produto apenas.
Evitar desperdício é uma boa prática da Visão Ágil.
Pois é. É o renomado "matar mosca com um canhão". Este é um dos motivos pelo qual postei. Porque uma vez que apenas irei controlar o path das fotos do produto, penso em algo simples, porém, viso também a reutilização, legibilidade e as boas práticas OO - a qual estou estudando X)
cmoscoso wrote:+1
List<Foto> fotos;
Ao que entendi, vocês sugerem que na entidade Produto, haja o ArrayList das fotos, pois é uma composição do Produto (as fotos). Assim sendo, toda a responsabilidade de manipular as Foto(s) ficará a cargo da entidade Produto, correto ?
Por exemplo:
Ele irá correr o ArrayList produtos e irá verificar se bate o path, com o path que quero remover:
Do ponto de vista da reutilização, isso não seria ruim ? Pois se eu for reutilizar o Foto para outro fim, terei que montar sua implementação novamente (não em sua totalidade, pois pontos poderão mudar) mas em termos gerais serão duplicado sim.
O que acham ?
Agradeço a todos !
|
 |
|
|
|
|