Opinião sobre modelagem de um sistema

Boa tarde a todos!
Gostaria de saber a opinião de vcs a respeito de um sistema que envolverá diversos módulos, sendo como exemplo os módulos de Folha, Livros e Contabilidade.
Analisando uma parte que será crucial para o projeto, que é o cadastro de Pessoas (a idéia é ter um cadastro único para todos módulos) chegamos a dois modelos:

Modelo 1:

Modelo 2:

Os atributos das classes foram omitidos e cada classe terá atributos próprios.
As classes que fazem parte de um determinado módulo devem ter os atributos segundo uma hierarquia, ex:

Pessoa -> PessoaContabil - > ClienteContabil e FuncionarioContabil devem ter os campos de PessoaContabil.

Esse sistema teria que ser projetado de forma modular, sendo que o cliente desse sistema poderá apenas ter o módulo Contábil por exemplo.

No modelo 1, as classes como Pessoa, Cliente e Funcionario acabam tendo um forte acomplamento entre as classes mais especializadas pois elas deveram ter uma instancia de todas as classes que seriam mais especializadas (Ex: a classe Cliente deve ter instancias de ClienteLivros, ClienteContabil, ClienteFolha, devido o uso do relacionamento 1 para 1).

Supondo que meu cliente tenha uma tela de cadastro de Clientes na qual haverá uma aba Geral com os dados pertinentes a Pessoa, uma aba Contabil, com os dados de PessoaContabil e ClienteContabil e uma aba Folha com os dados de PessoaFolha e ClienteFolha.
Utilizando o modelo 2, eu deveria criar 3 objetos, um para cada módulo (Cliente, ClienteContabil e ClienteFolha). O que no modelo 1 eu poderia apenas criar um objeto do tipo Cliente e ir setando os campos.

Qual é a opinião de vcs a respeito desses modelos?

Amigo,

Sem muito embasamento teórioco ou até mesmo prático pra responder…

Gosto mais do modelo 2.

Abraços.

Bem, sem os requisitos fica difícil de opinar mas vamos tentar …

Cada Módulo, pode ter uma fachada de entrada se você achar necessário.

Qual a relação entre Cliente e Pessoa? O que difere os dois?

Existe mesmo a necessidade de ter esse monte de Cliente* e Pessoa*?

Cuidado com BDUF. IMO desenvolver utilizando técnicas como TDD e Refactoring te darão um resultado melhor.

[]s

Olá!

Para deixar mais claro, vou supor que os requesitos sejam esses:

  • Modelar um sistema que unifique um cadastro de Clientes e Funcionários entre os módulos de Livros Fiscais, Contabilidade, e Folha de Pagamento.
  • Ter um módulo básico que contém todas informações que são iguais entre esses módulos.
  • As informações que serão compartilhadas de um módulo e outro ficarão no modulo Básico, as que são específicas de um módulo,
    ficarão apenas vísiveis em seu módulo.
  • O sistema deverá ser feito de forma modular, sendo que o cliente pode escolher quais módulos ele irá ter (o básico sempre irá), podendo adquirir módulos novos posteriormente.

A partir desses requesitos, começaria modelando o módulo básico, colocando todas informações que são comuns a todos os outros módulos. E vejo que os outros módulos serão extensões desse módulo básico Provavelmente esse módulo sofrerá refatorações para abrigar campos que futuramente possam surgir. (Por exemplo, ao término de implementação do módulo Contábil, verifico que algum campo do módulo de Livros tb precisa da mesma informação, então irei colocar essa informação no módulo básico).

As classes Pessoa, Cliente e Funcionário, são basicamente o módulo básico, pois elas contêm as informações que todos os módulos utilizarão.
Um Cliente e um Funcionário, devem ter todos campos de Pessoas (como por exemplo Nome), e mais os campos específicos de cada um. Tb deverá ter a possibilidade de um Cliente em determinado ser um Funcionário tb!

Para modelar os outros módulos, eu vejo que teria que criar classes como PessoaContabil, ClienteContabil, FuncionarioContabil, pois uma Pessoa no módulo contábil irá ter coisas adicionais, assim como Cliente e o Funcionário. O mesmo vale para os demais módulos.

Espero ter sido mais claro.

Desde já agradeço.

Por isso que você não precisa de ClienteLivros, ClienteFolha e ClienteContabil. utilize cliente onde você precisar. Provavelmente essas classes devem ser para fazer outras coisas e teriam outros nomes.

[quote=IcedSlayer] Um Cliente e um Funcionário, devem ter todos campos de Pessoas (como por exemplo Nome), e mais os campos específicos de cada um.[quote]
Você tem que avaliar direito a necessidade da herança simplesmente para aproveitar campos. Em alguns casos isso pode te atrapalhar muito. Se for para aproveitar um campo nome apenas não acho que vai valer a pena.

[quote=IcedSlayer]Para modelar os outros módulos, eu vejo que teria que criar classes como PessoaContabil, ClienteContabil, FuncionarioContabil, pois uma Pessoa no módulo contábil irá ter coisas adicionais, assim como Cliente e o Funcionário. O mesmo vale para os demais módulos. [quote]
O que seriam essas coisas adicionais? Não estou entendendo muito bem. Isso não são requisitos. Você já está dizendo direto as classes do seu sistema. É importante saber o que o sistema faz em cada módulo. De qualquer maneira, continuo sugerindo que você desenvolva de maneira incremental ao invés de tentar modelar o sistema inteiro usando a prática de BDUF que citei no post anterior.

Posta os requisitos.

[]s

Olá

Por isso que você não precisa de ClienteLivros, ClienteFolha e ClienteContabil. utilize cliente onde você precisar. Provavelmente essas classes devem ser para fazer outras coisas e teriam outros nomes.
[/quote]

Eu entendo que eu precisaria essas classes, pois por exemplo ClienteLivros terá campos referentes a Cliente que são específicos de livros, e assim por diante!

Concordo plenamente contigo, caso fosse só para o campo nome, mas isso foi apenas um exemplo, a classe Pessoa irá ter diversos outros campos.

Seriam o mesmo caso acima, um FuncionarioContabil, teria informações específicas de um funcionário, que só o modelo de contabilidade irá ver.

Minha idéia é desenvolver de maneira incremental, idenficando todo o básico, para depois partir para a contabilidade. Não gostaria de depender de o que o módulo de Livros faz enquanto o modelo a Contabilidade, assim nao estaria evitando o modelo em cascata?
Se eu tiver que saber o que cada módulo irá ter de antemão, eu não estaria utilizando BDUF que nem vc falou?

Toda vez que vejo um modelo com classe “Pessoa”, eu torço o nariz. Quase sempre esta classe vem acompanhada de herança com a única intenção de facilitar a vida do desenvolvedor (o que na prática não acontece). Costumeiramente, este tipo de herança faz a economia de campos repetitivos que possa existir de classes em comum, mas não possui utilidade nenhuma quanto a seus métodos.

Cliente é cliente, Funcionário é funcionário e por aí vai. Você pode reunir dados em comuns em VOs (DDD e não CoreJava) do tipo Perfil ou DadosCadastrais e usar composição para reaproveitar estes campos (e não uma herança desnecessária).

O seu modelo esta sendo basicamente uma reciclagem de atributos e não a representação de um Domínio, pondere isso (posso estar enganado, mas essa é a impressão que se tem olhando o diagrama com as omissões de métodos e atributos).

Sinceramente, só vejo um modelo com uma entidade “Pessoa” que faça sentido, caso exista outras entidades como Cachorro, Papagaio, ExtraTerrestre…

Nenhum dos modelos funciona. Eles são demasiado hierarquicos.
Cliente não é uma pessoa. Logo herança não funciona.
Como assim, não é pessoa ?

Uma pessoa pode ser cliente ou fornecedor ou os dois. É facto dela poder ser os dois que indica que
o cliente não é uma pessoa, a pessoa é que é um cliente. Cliente/Vendedor/fornecedor/Empregado/contribuinte, etc são papeis que a pessoa assume em diferentes cenários.

Existem informações especiais associadas a cliente/fornecedor/etc… que não estão relacionadas à pessoa, mas sim ao papel de cliente/etc… como pro exemplo: endereço de entrega/ endereço de cobrança.
Estes atributos pertencem à classe cliente/etc… mas não à pessoa. Então o modelo mais realista - e por conseguinte mais simples é :

class Cliente{

    Pessoa pessoa;
}

Os diferentes módulos precisam de diferentes dados. Cliente do ponto de vista contábil é diferente do ponto de vista comercial que é diferente do tributário… Aqui existem duas soluções:
Criar uma hirarquia de tipos de cliente com várias classes, ou criar uma só classe com diferentes interfaces.
Os modulos deveriam manipular interfaces. Isto porque os dados reais são os mesmos mas vistos de diferentes formas. Classes adpadoras poderiam fazer a ponte ( Veja o padrão Bridge). Isto porque os modulos podem evoluir de formas distintas e criar heranças pode destruir os modulos se demasiadas alterações forem feitas.

Como eu já tinha dito e o Alessandro reforçou, ter herança pra aproveitar campos não é uma boa idéia. E agora eu também reforço o que ele falou. Se der pra aproveitar faça via composição.

Como eu já tinha dito e o Alessandro reforçou, ter herança pra aproveitar campos não é uma boa idéia. E agora eu também reforço o que ele falou. Se der pra aproveitar faça via composição.

[/quote]

Desculpa estou comecando em modelagem, nao conseguir entender por que não e uma boa ideia ter heranca sendo que sao os mesmos atributos…

Como eu já tinha dito e o Alessandro reforçou, ter herança pra aproveitar campos não é uma boa idéia. E agora eu também reforço o que ele falou. Se der pra aproveitar faça via composição.

[/quote]

Desculpa estou comecando em modelagem, nao conseguir entender por que não e uma boa ideia ter heranca sendo que sao os mesmos atributos…[/quote]

Herança não serve para reaproveitar atributos e sim para criar hierarquias. O fato da hierarquai ter os mesmos atributos é um detalhe. Por exemplo, pessoas têm idade e prédios tb. mas pessoas não são prédios nem prédios são pessoas. Para usar herança tem que haver uma forte relação. A famosa relação É-UM…

Olá, primeiramente gostaria de agradecer as opiniões dadas, certamente foram de muito valor!

Estive revendo esse modelo, e chego em um problema que ainda nao achei uma solução:

Supondo que eu queira começar a desenvolver o básico sem me preocupar com os demaia módulos, deixando-os para serem implementados depois. Para exemplo, vou reduzir o escopo de minha modelagem, apenas para a classe Cliente.
Então eu crio uma classe Cliente, e nela coloco apenas informações básicas de um Cliente.
Estando pronto o módulo básico, irei modelar o módulo Contábil, nesse módulo deverei ter um Cliente com informações mais especializadas ( utilizando uma hirarquia de tipos de cliente ou criando uma só classe com diferentes interfaces, como o sergiotaborda deu a idéia).
Agora supondo que eu irei modelar o módulo de Folha, que por sua vez irá ter dados específicos de Folha, então faço a mesma coisa que fiz para o módulo Contabil. Como modelei o módulo básico independente do módulo dos outros, meu módulo de Folha e Contabil, podem ter campos em comum! E isso pode quebrar um dos requesitos do sistema que era ter um cadastro único, ou seja, se o cliente tem apenas os módulos Básico e Contábil e ele deseja adquirir o módulo de Folha, ele irá apenas digitar os campos específicos de Folha para aquele cliente, aproveitando todos os dados digitados anteriormente!
Isso sem falar que podem haver outros módulos (Livros, Industrial, Comercial), e certos módulos terem alguns campos em comum com outros módulos!

Como vcs gerenciariam isso tudo?

Dizem por ai que em OO vc deve se aproximar do mundo real.

Vc tem uma classe Pessoa, uma classe Cliente e uma classe Funcionario que nao estao na mesma árvore de herança.
Por acaso seus clientes e funcionarios são animais?

E quando eu tenho um cliente que como vc mesmo disse, não é uma pessoa? o objeto pessoa fica null?

[quote=fabiocsi][quote=sergiotaborda]
Então o modelo mais realista - e por conseguinte mais simples é :

class Cliente{

    Pessoa pessoa;
}

[/quote]

E quando eu tenho um cliente que como vc mesmo disse, não é uma pessoa? o objeto pessoa fica null?[/quote]

O cliente não é uma pessoa no sentido de herança. A relação É-UM não se aplica. Cliente TEM-UMA pessoa.
Se a pessoa é null o cliente não tem uma pessoa. Logo esse estado do objeto cliente é incoerente. Para que haja cliente , primeiro tem que haver pessoa (mesmo que ela seja um extra-terrestre).
Ou seja, pessoa nunca é null.

[quote=fabiocsi]Dizem por ai que em OO vc deve se aproximar do mundo real.

Vc tem uma classe Pessoa, uma classe Cliente e uma classe Funcionario que nao estao na mesma árvore de herança.
Por acaso seus clientes e funcionarios são animais?[/quote]

Acho que vc não entendeu o conceito de herança.
Se cliente é uma pessoa e fornecedor é uma pessoa , eles podem ser a mesma pessoa ?
A resposta é SIM.
Esta resposta mostra que cliente e fornecedor não são herarquias de pessoa. (porque ambos podem estar presentes ao mesmo tempo). Logo, herança não se aplica. Ou clientes e fornecedores são animais já que pessoas são animais, mas é o fato de uma pessoa poder ser todos os papeis que faz com que não se possa usar herança;
Esta modelagem de que cliente é uma pessoa e fornecedor é uma pessoa leva a que a mesma pessoa não possa ser ambos. Isso é um erro comum. Até em sistema grandes como o microsiga.
Não cai nesse erro. Clientes são designados pelo numero de cliente e tem uma , ou mais, pessoas associadas.
Fornecedores idem, etc…

Realmente OO tem que estar o mais perto da realidade possivel, mas dizer que Cliente herda de pessoa não é realista.

[quote=IcedSlayer]Olá, primeiramente gostaria de agradecer as opiniões dadas, certamente foram de muito valor!

Estive revendo esse modelo, e chego em um problema que ainda nao achei uma solução:
(…)
Como vcs gerenciariam isso tudo?[/quote]

Realmente esse é um problema complexo. A melhor solução que encontrei até agora (é u mtrabalho em progresso) é a seguinte:

Cria-se um mecanismo de metadados. Estes metadados são usados pelo mecanismo de persistencia para criar as tabelas no banco automaticamente.
O sistema de persistencia retorna objetos que segue o padrão proxy. Para isso cada entidade (cliente, fornecedor, etcc) é definida numa interface. O proxy usa reflection para responder aos get/set da interface. Não existe um objeto de negocios, existe uma interface.

O modulo padrão tem uma interface Cliente. O module contábil que extende o modulo padrão tem uma interface ClienteContabil que herade Cliente. E assim vai…

O proxy pode ser de dois tipos:

  1. cada interface corresponde a uma tabela. todas as tabelas mos modulos especiais ligam com a tabela do modulo padrão. Assim cada chamada a um metodo da interface é canalizada para os dados da tabela correta
  2. todas as interfaces mapeiam para uma só tabela. Assim campos comums entre os modulos especiais permanecem num só lugar.

O ponto ruim deste modelo é que não ha como implementar logicas nos objetos de negocio. Eles viram apenas objetos de dados. Existe uma forma de colocar metodos atrvés de uma classe implmentadora e um proxy bem inteligente. Com closures no java 7 isto deve ser mais simples. Contudo ainda é muito complicado.
Acabaremos tendo um sistema que separa os dados das operações associadas a eles. Contudo num sistema multi-modulo isso pode não ser tão ruim assim.

[quote=sergiotaborda][quote=fabiocsi]Dizem por ai que em OO vc deve se aproximar do mundo real.

Vc tem uma classe Pessoa, uma classe Cliente e uma classe Funcionario que nao estao na mesma árvore de herança.
Por acaso seus clientes e funcionarios são animais?[/quote]

Acho que vc não entendeu o conceito de herança.
Se cliente é uma pessoa e fornecedor é uma pessoa , eles podem ser a mesma pessoa ?
A resposta é SIM.
Esta resposta mostra que cliente e fornecedor não são herarquias de pessoa. (porque ambos podem estar presentes ao mesmo tempo). Logo, herança não se aplica. Ou clientes e fornecedores são animais já que pessoas são animais, mas é o fato de uma pessoa poder ser todos os papeis que faz com que não se possa usar herança;
Esta modelagem de que cliente é uma pessoa e fornecedor é uma pessoa leva a que a mesma pessoa não possa ser ambos. Isso é um erro comum. Até em sistema grandes como o microsiga.
Não cai nesse erro. Clientes são designados pelo numero de cliente e tem uma , ou mais, pessoas associadas.
Fornecedores idem, etc…

Realmente OO tem que estar o mais perto da realidade possivel, mas dizer que Cliente herda de pessoa não é realista.[/quote]

Enteder o conceito de herança eu entendi sim e muito bem. Se quiser podemos ficar paginas discutindo sobre isso entao vc terá uma noção melhor do que eu entendo por herança.

A questao aki é que vc esta defendendo o ponto de NAO SE APLICAR herança nesse caso. Ai são outros 500.

[quote=IcedSlayer]Olá, primeiramente gostaria de agradecer as opiniões dadas, certamente foram de muito valor!

Estive revendo esse modelo, e chego em um problema que ainda nao achei uma solução:

Supondo que eu queira começar a desenvolver o básico sem me preocupar com os demaia módulos, deixando-os para serem implementados depois. Para exemplo, vou reduzir o escopo de minha modelagem, apenas para a classe Cliente.
Então eu crio uma classe Cliente, e nela coloco apenas informações básicas de um Cliente.
Estando pronto o módulo básico, irei modelar o módulo Contábil, nesse módulo deverei ter um Cliente com informações mais especializadas ( utilizando uma hirarquia de tipos de cliente ou criando uma só classe com diferentes interfaces, como o sergiotaborda deu a idéia).
Agora supondo que eu irei modelar o módulo de Folha, que por sua vez irá ter dados específicos de Folha, então faço a mesma coisa que fiz para o módulo Contabil. Como modelei o módulo básico independente do módulo dos outros, meu módulo de Folha e Contabil, podem ter campos em comum! E isso pode quebrar um dos requesitos do sistema que era ter um cadastro único, ou seja, se o cliente tem apenas os módulos Básico e Contábil e ele deseja adquirir o módulo de Folha, ele irá apenas digitar os campos específicos de Folha para aquele cliente, aproveitando todos os dados digitados anteriormente!
Isso sem falar que podem haver outros módulos (Livros, Industrial, Comercial), e certos módulos terem alguns campos em comum com outros módulos!

Como vcs gerenciariam isso tudo?[/quote]

Tem MSN ou e-mail!? Se preferir mande uma mensagem em PVT.

[quote=sergiotaborda][quote=fabiocsi]Dizem por ai que em OO vc deve se aproximar do mundo real.

Vc tem uma classe Pessoa, uma classe Cliente e uma classe Funcionario que nao estao na mesma árvore de herança.
Por acaso seus clientes e funcionarios são animais?[/quote]

Acho que vc não entendeu o conceito de herança.
Se cliente é uma pessoa e fornecedor é uma pessoa , eles podem ser a mesma pessoa ?
A resposta é SIM.
Esta resposta mostra que cliente e fornecedor não são herarquias de pessoa. (porque ambos podem estar presentes ao mesmo tempo). Logo, herança não se aplica. Ou clientes e fornecedores são animais já que pessoas são animais, mas é o fato de uma pessoa poder ser todos os papeis que faz com que não se possa usar herança;
Esta modelagem de que cliente é uma pessoa e fornecedor é uma pessoa leva a que a mesma pessoa não possa ser ambos. Isso é um erro comum. Até em sistema grandes como o microsiga.
Não cai nesse erro. Clientes são designados pelo numero de cliente e tem uma , ou mais, pessoas associadas.
Fornecedores idem, etc…

Realmente OO tem que estar o mais perto da realidade possivel, mas dizer que Cliente herda de pessoa não é realista.[/quote]

Você adcionar meu msn para a gente conversar sobre java?
alan.silva@ticorporate.com.br