Pessoal, estou participando de um projeto que possui vários sistemas com alguns pontos relacionados.
Explicando melhor, tenho um sistema de emissao de Nota Fiscal e outra de Declaração de Notas. Esses dois sistemas tem quase todo o modelo de dados identico, mas existem algumas diferenças, e algumas funcionalidades de um sistema servem para o outro.
Enfim, a intenção do gestor do projeto é que o modelo de classes destes dois sistema sejam compartilhados, desta forma, nós teriamos um projeto em separado só com as classes de dominio que modelam um contexto unico mas que engloba as situações dos dois sistemas e para tanto, na aplicação web de ambos os sistemas existirá um jar que representa esse conjunto de classes de dominio compartilhados por ambos os sistemas.
Na pratica tudo parece lindo, ou seja, eu teria em um projeto separado por exemplo, a classe NotaFiscal, que teria regras de negocio de ambos os sistemas. No entanto, estou com alguns problemas de definição deste modelo integrado de classes. O principal é o hibernate; uso o hibernate e portanto eu espero que as classes do meu modelo de dominio sejam as mesmas classes utilizadas para mapeamento objeto relacional de cada sistema, acontece que como disse anteriormente, apesar da grande semelhança um sistema tem algumas particularidades de outro, como fazer então para que a mesma classe represente mapeamentos diferentes. Se eu tivesse um modelo de dominio unico compartilhado, mas separado das classes de mapeamento do hibernate em que cada sistema teria o seu, seria mais facil, no entanto, acredito que isso nao é o correto.
Enfim, será que é possivel esse tipo de integração entre sistemas, faze-los compartilhar um modelo de dominio de classes, para reaproveitar pontos em comum?
Algumas ideias:
) Não usar o hibernate
) Não usar modelo compartilhado
) Construir um meta-modelo , ou seja, um modelo que contém tudo o que é comum
e a partir desse contruir os outros dois modelos a partir de herança.
Assim vc tem o que é comum em um só lugar mas tem dois modelos separados para o hibernate entender.
Olá !
Você pode compartilhar o que é comum através de composição, onde nessas entidades onde realmente é comum o mapeamento é o mesmo, e vc cria outras classes com os atributos específicos e mapeamentos específicos.
Só toma cuidado com o cache do hibernate nessas duas aplicações hein, é fácil de dar zica… muito fácil !!
[]´s
Provavelmente existe uma confusão sobre o que é de cada sistema. O ideal é que cada um tenha seu Domínio e troquem mensagens via algum protocolo (e.g. REST, RMI (EJB), SOAP, etc.).
Se você puder dar um exemplo concreto de alguma coisa em comum dos 2 sistemas eu posso tentar ajudar.
Cada vez mais tenho concluido que o melhor é realmente manter dominio separados, acho que tentar fazer algo conjunto se realmente for possível só vai gerar é mais problemas e inclusive vai aumentar consideravelmente o custo de manutenção devido a mudanças que podem refletir em outro sistema, vai ser complicado.
Mas quem sabe, vamos discutir mais um pouco.
Emerson, os dois sistemas tem todo o modelo de endereçamento (Pais,Estado, Cidade, Logradouro) igual, também a a parte de cadastro de Pessoa, Empresa, Contato, Documento em comum, além também da parte de Atividade, Servicos, Aliquotas e bla bla bla, também em comum.
Ou seja, o que difere de ambos é a parte Nota Fiscal, um dos sistema gera a Nota Fiscal enquanto outro serve para declarar as NotasFiscais, neste contexto, meu modelo tem o seguinte, uma super classe DocumentoFiscal (compartilhado) e as sub-classe NotaFiscal (do sistema de geracao de nota fiscal) e DocEmitido e DocRecebido (sistema de declaração de nota fiscal e outros documentos fiscais). Desta forma, o sistema de declaração de nota fiscal poderia inclusive aproveitar do objeto nota fiscal que inicialmente era só do outro sistema para por exemplo buscar as notas fiscais emitidas por certa pessoa, para fazer uma declaração automatizada, ao invés de ter de digitar tudo.
Compreendeste?
Provavelmente a maioria dos seus objetos pertence ao Domínio do sistema que declara (ou cadastra) as notas fiscais. O sistema que gera as notas irá consumir serviços para obter as informações necessárias.
De qualquer forma, eu não entendi o motivo de ter 2 sistemas. Existe algum requisito que te impeça de gerar a nota no mesmo sistema que faz o cadastro da mesma?
[quote=Emerson Macedo]
De qualquer forma, eu não entendi o motivo de ter 2 sistemas. Existe algum requisito que te impeça de gerar a nota no mesmo sistema que faz o cadastro da mesma?[/quote]
Sim, o sistema que gera é web, enquanto que o sistema que declara ela é desktop
Nesse cenário, onde só muda o frontend, será que não compensa vc ter somente módulos separados ?
O que eu quero dizer ?
Criar um módulo onde está todo o seu domínio (entidades da declaração e emissão da nota), e dois outros módulos que seriam sua GUI, um para Web e outro para Desktop.
Você não cria uma complexidade particionando seu domínio, e ainda por tabela consegue separar bem sua interface, deixando livre para no futuro implementar telas que estão em Web para Desktop e vice-versa, sem grandes traumas, afinal seu domínio está em outro módulo.
[]´s
[quote=spranta][quote=Emerson Macedo]
De qualquer forma, eu não entendi o motivo de ter 2 sistemas. Existe algum requisito que te impeça de gerar a nota no mesmo sistema que faz o cadastro da mesma?[/quote]
Sim, o sistema que gera é web, enquanto que o sistema que declara ela é desktop
[/quote]
Nesse caso, você tem a opção de ter apenas um Domínio e ter uma camada de aplicação disponível para as duas UIs. A UI desktop vai estar num TIER diferente. Portanto, você pode usar uma Fachada Remota ou alguma outra técnica. A Web UI você não precisará usar nada disso pois apesar de estar num LAYER diferente, pode ficar no mesmo TIER que está sua camada de aplicação e Dominio.
Olá Reinaldo,
Até o momento, é justamente isso que estamos fazendo. Temos um projeto chamado model-core que possui todas as ditas classes de dominio compartilhadas, seus DAO’s e algumas classes Services. Enquanto que abaixo temos dois sub-projetos (módulos), o sistema web e o sistema desktop, que dependem (Required Projects do Eclipse) os dois do model-core e fazem uso das classes ali criadas, desta forma é que estamos compartilhando o modelo, e desta forma então durante a distribuicão de cada módulo, cada um leva junto consiguo um model-core.jar
Meu problema é que não é mudado somente o front-end, esta não é a diferença destes módulos, as aplicações tem proposito de negocio diferentes, tem funcionalidades diferentes, mas o apoio delas, principalmente aqueles cadastros auxiliares são quase que iguais. Então minha dúvida seria como conseguir reaproveitar em ambos os modulos, estas classes criadas no model-core levando-se principalmente em consideração o fato de tais classes serem as classes de mapeamento objeto-relacional do hibernate e que além disso cada sub-modulo tem uma ou outra diferença no mapeamento de algumas classes (Endereco por exemplo), e se essa maneira (criando este tal model-core) seria a melhor escolha de se fazer isso mesmo ou é melhor manter tudo cada um com seu dominio proprio e quando ouver necessidade de troca de serviços eu invoco o serviço remotamente via algum protocolo como disse o Emerson?
Existe um porem. A aplicação desktop será em sua grande parte de execução, uma aplicação off-line, portanto ela nao pode invocar o dominio remotamente, minha intenção nesta historia toda é saber se a melhor opção seria mesmo fazer um modelo integrado de ambos os modulos (mesmo com todos estes problemas que o hibernate pode me causar em função disso) e distribuir isto via um jar colocado em cada sub-sistema ou se eu deveria deixar tudo separado mesmo.
Tem uma opção, que junta boa parte do que todos falaram, seria uma divisão de módulos(sub-sistemas, projetos do eclipse, etc.) algo assim :
[list]
dominio-geral
dominio-especifico-emissão-NF
dominio-especifico-declaração-NF
web-gera-NF
desktop-emite-NF
[/list]
Aí vamos supor um exemplo de Endereço como vc citou, vou criar alguns atributos de mentira ai só pra exemplificar :
Essa aqui tá no “domínio-geral”, e tem seu próprio mapeamento.
public class Endereco {
private Long id;
private String logradouro;
...
public String getLogradouro(){
return this.logradouro;
}
...
}
Essa aqui tá no “domínio-emissão-nf” e também tem seu próprio mapeamento, e a classe de composição que tá dentro dela não tem um novo mapeamento, ela usa o do outro módulo.
public class EnderecoEmissao {
private Endereco endereco;
private String portaoEntrega;
...
public String getLogradouro(){
return this.endereco.getLogradouro();
}
}
Eu tenho uma estrutura parecida com essa, mas eu uso o maven, então ele me ajuda bastante, pois tem resources que são compartilhados também, ele já explode pra mim dentro as dependências e me adianta um lado, mas vc consegue fazer com as dependencias de projetos do eclipse que vc comentou.
Assim vc reaproveita o código, mas só tem que ver se o seu domínio continua representando a visão idealizada pelo cliente/analista. As vezes não vale a pena tanto aproveitamento se tudo ficar rebuscado.
Hum… agora que eu vi a parte de ser offline…
Eh isso pode mudar um pouco os requisitos, e de repente o compartilhamento do domínio, ou pelo menos o mapeamento podem ser diferentes hein.
Pq offline, geralmente não combina muito com banco de dados pesado ou coisa assim, pode ser que realmente tenha um domínio ou mapeamento separado para o desktop.
Se o domínio é diferente, então o Domain Model é diferente. Um avião voa feito um pássaro, mas possui comportamento e características diferentes, é uma outra entidade.
Só compartilhe domínio, se vc tem certeza que ele realmente representa o mesmo domínio em todos os sentidos e não apenas em similaridade.
Tudo bem, vai ser offline, mas como é que a aplicação online que gera as NFs vai acessar as informações geradas pela offline? Não entendi muito bem isso. Em algum momento as informações cadastradas por essa aplicação offline terão que ser disponibilizadas para essa online gerar as NFs. Pode explicar qual é a linha que vocês estão seguindo pra fazer isso acontecer?
Reinaldo, o caminho tomado até agora tem sido justamente esse ai que voce citou, no entanto, é complicado de ter dois mapeamentos distintos mas referenciando as mesmas classes (que seriam os POJOS utilizados pelo Hibernate).
[quote]
Tudo bem, vai ser offline, mas como é que a aplicação online que gera as NFs vai acessar as informações geradas pela offline? Não entendi muito bem isso. Em algum momento as informações cadastradas por essa aplicação offline terão que ser disponibilizadas para essa online gerar as NFs. Pode explicar qual é a linha que vocês estão seguindo pra fazer isso acontecer?[/quote]
Talvez essta tenha sido a confusão até agora e que eu não consegui me expressar bem.
Acontece que a aplicação de declaração da NFS-e não vai precisar (pelo menos até o momento) se comunicar coma aplicação on-line, elas não vão trocar mensagens, não quero ter um dominio compartilhado para esse fim.
Apesar delas terem um ponto bem em comum além de toda a estrutura de dados auxiliar que citei (endereço, atividade, …), é que na aplicação de geração eu tenho a Classe NotaFiscal e na aplicação de Declaração eu tenho a classe DocumentoFiscal (pode ser nota fiscal, pode ser boleto, …) desta forma a aplicação de Declaração poderia utilizar a Classe de NotaFiscal para tratar o Documento Fiscal quando ele for do tipo Nota Fiscal.
Mas sendo mais direto, minha intenção é que como elas (as aplicações) tem quase o mesmo modelo de dados, então o mapeamento objeto-relacional delas naquilo que é comum poderia ser reaproveitado , mas pelo que estou vendo eu estaria reaproveitando somente uma estrutura de dados da classe (a declaração dos atributos), e como o comportamento é distinto, ele não seria reutilizado, já não sei se compensa todo esta complexidade ao invés de isolar cada modelo de dominio.
Eu tenho uma grande parte do dominio de ambos os sistemas que são identicos, não deveria isso ser compartilhado?
[quote=spranta]Talvez essta tenha sido a confusão até agora e que eu não consegui me expressar bem.
Acontece que a aplicação de declaração da NFS-e não vai precisar (pelo menos até o momento) se comunicar coma aplicação on-line, elas não vão trocar mensagens, não quero ter um dominio compartilhado para esse fim.[/quote]
Sinceramente eu não entendi. Se eles não se comunicam, como a aplicação online vai gerar as NFs que foram cadastradas pela aplicação offline?
Olha o que você disse em outro post:
Com base nessa afirmação anterior e no que você está me dizendo agora, eu não to é entendendo mais nada…
Pode explicar melhor isso?
É o inverso do que você está pensando.
Primeiro eu tenho um sistema web que gera a NF.
Depois eu tenho um sistema desktop que declara as NF’s geradas por mim e as NF’s tomadass por mim (aquelas que a minha empresa pegou de outros prestadores), lembrando que eu posso nem estar utilizando o sistema web para geração de NF, eu poderia fazer a geração de NF manualmente e portanto somente utilizar o sistema desktop que declara para o governo as minhas notas fiscais emitidas e aquelas recebidas.
Ah tá. Agora eu entendil. Se você tivesse explicado isso no começo ficaria bem mais fácil.
Agora o que eu acho é que você tem 2 Domínios completamente diferentes. Por que? Simplemente porque Nota Fiscal para o sistema que gera não tem nada a ver com a Nota Fiscal para o sistema que registra. Portanto, abrigam conceitos diferentes. Portanto, cada sistema terá sua NF para fins diferentes. O que eu quero dizer com isso?
Imagine um objeto Funcionario. Você não iria ter um comportamento irAoBanheiro() por exemplo em um Sistema RH. Mas se esse objeto Funcionario fosse de um software tipo um SecondLife da vida, onde ele precisa andar, correr, etc, talvez esse comportamente faça sentido.
Essa analogia foi meio grotesca mas é pra mostrar que o objeto tem que fazer sentido em um contexto e não necessariamente em mais de um.
No seu caso, e principalmente como os sistemas não se integram de forma alguma, você terá um objeto NotaFiscal que terá estado e responsabilidades relacionadas a geração de Notas Fiscais e outro que pelo que eu entendi do seu sistema nem terá responsabilidades pois parece ser um simples cadastro.
Isto mesmo Emerson, me desculpe por nao ter sido tão claro no inicio do post, é que as vezes a gente que tá trabalhando no problema já assume os conceitos mais facilmente e nao explicamos tao detalhadamente aos outros.
Mas entao, com relação a entidade NotaFiscal, vejo que realmente eles são distintos entre os dois sistemas, no entanto, e o restante do modelo que ambos os sistemas tem muito em comum, são cerca de umas 40 tabelas que são identicas para ambos os sistemas e que poderiam ser mapeadas pelo hibernate igualmente para ambos. Voces nao acham que isso poderiam ser parte de um dominio compartilhado?