Duvida de auto-relacionamento em DER e UML

Ola Pessoal,

Estou fazendo a analise de um projeto MRP para o TCC de uma empresa que trabalha com fabricação de componentes eletronicos. Na fabricação de itens, 1 item é composto por N itens na qtd X e 1 item compoe N itens na qtd X, entao temos um relacionamento unario(uma classe que se relaciona com ela mesma) ou auto-relacionamento de N pra N.

No modelo DER, creio que ficaria assim:
tabela item

  • id_item
  • nm_item

tabela itemComposicao

  • id_item_composto -> E item.id_item
  • id_item_insumo -> E item.id_item
  • qtde

Duvida:
Se esse DER esta certo, como representariamos ele no diagrama de classe, haverá 2 classes como no DER ou uma só? e no codigo proprieamente dito, como vai ficar?

Obrigado

Respostas:

  1. Esse DER esta certo?
    Depende, use auto-relacionamento; se o seu banco suportar. Caso contrario, se entendi direito, vai acabar sendo um relacionamento N x N mesmo.

  2. Como representariamos ele no diagrama de classe?
    Uma classe com uma associação de cardinalidade 0 x N apontando para ela mesma.

  3. Haverá 2 classes como no DER ou uma só?
    Uma só.

  4. E no codigo proprieamente dito, como vai ficar?

public class Item { private List<Item> itens = new ArrayList<Item>(0); // Outros atributos ... // Métodos ... }

flws

O banco é mySQL e suporta sem problemas o auto-relacionamento de N x N. Ou seja, Meu DER esta certo!

Não seria N x N? pois um item pode compor varios itens e um item pode ser composto por varios itens

Ok

Como vc diz que a classe Item é composta por um determinado item na qtd 2?
Exemplo: fabrico bicicleta, e pra fabricar bicicleta preciso dizer que o item bicicleta é composto por item roda na qtde 2, o mesmo item bicicleta é composto por um item quadro na qtde 1.

Vlw!

To achando um pouco estranho este teu modelo. Voce trata tudo com item, nao seria o caso de tratar por exemplo como PRODUTO e materia prima? ou Produto e Itens do Produdo?
Por exemplo o item bicicleta NUNCA sera usado para montar outro item.

Acho que voce poderia rever teu modelo, deveria por ex. tratar bicicleta como um produto que necessita de varios itens para se montar.

e ficaria + ou - assim:

Produto M------------contem------------N Itens

A nao ser que a empresa fabrique tudo do zero, ai teria que ver, mas pelo que entendi do teu modelo, todo item que é montado, depois disso NUNCA sera usado para montar outro item, entao poderiamos chama-lo de produto final, e os itens de materia prima.

Deu pra entender :?: :?

mas que concidencia… acabei de postar uma duvida parecida: http://www.guj.com.br/posts/list/132535.java

porem um pouco diferente:

se tivermos:


class Item {

 private Coisa coisa;

 public Coisa() {
   item = new Coisa();
 }

}

class Coisa{

  private Item item;
  
  public Coisa() {
    item = new Item();
  }

}

Teremos um belo problema de referencia circular…
como evito isto?

[quote=fredferrao]To achando um pouco estranho este teu modelo. Voce trata tudo com item, nao seria o caso de tratar por exemplo como PRODUTO e materia prima? ou Produto e Itens do Produdo?
Por exemplo o item bicicleta NUNCA sera usado para montar outro item.

Acho que voce poderia rever teu modelo, deveria por ex. tratar bicicleta como um produto que necessita de varios itens para se montar.

e ficaria + ou - assim:

Produto M------------contem------------N Itens

A nao ser que a empresa fabrique tudo do zero, ai teria que ver, mas pelo que entendi do teu modelo, todo item que é montado, depois disso NUNCA sera usado para montar outro item, entao poderiamos chama-lo de produto final, e os itens de materia prima.

Deu pra entender :?: :? [/quote]

Fred,

Legal o teu ponto de vista, mas um item que a empresa fabrica pode ser usado para fabricar outro item.

Ex: A empresa pode fabricar bicicleta e pneu de bicicleta. Vc concorda que eu posso usar esse mesmo pneu em um monociclo? (aquelas bicicleta de circo que só tem uma roda e 1 asento).

Não da pra tratar um pneu como materia prima, pq hora ele pode se comportar como materia prima(da bicicleta) e hora como produto final(um pneu que é composto de roda e camera, que são efetivamente materias primas de pneu).

vlw!

Aí é que está o ponto, um diagrama de classe não tem nada a ver com o MER. Semanticamente dizem a mesma coisa mas o no design são bem diferentes.

[quote=robisonsilvar]Como vc diz que a classe Item é composta por um determinado item na qtd 2?
Exemplo: fabrico bicicleta, e pra fabricar bicicleta preciso dizer que o item bicicleta é composto por item roda na qtde 2, o mesmo item bicicleta é composto por um item quadro na qtde 1. [/quote]

Ao observar o diagrama de classe vc verá a expressão que objetiva a atender as condições máximas. Por exemplo: você poderá ter um item que não é composto por mais nenhum (0…N), se o item for composto por 2 itens a cadinalidade ainda é verdadeira porque você pode ter 0 itens até N itens para compor.

Dá uma olhada em UML na parte de constraint que vc verá outras possibilidades de expressar restrições.

flws

[quote=robsonsilvar][quote=fredferrao]To achando um pouco estranho este teu modelo. Voce trata tudo com item, nao seria o caso de tratar por exemplo como PRODUTO e materia prima? ou Produto e Itens do Produdo?
Por exemplo o item bicicleta NUNCA sera usado para montar outro item.

Acho que voce poderia rever teu modelo, deveria por ex. tratar bicicleta como um produto que necessita de varios itens para se montar.

e ficaria + ou - assim:

Produto M------------contem------------N Itens

A nao ser que a empresa fabrique tudo do zero, ai teria que ver, mas pelo que entendi do teu modelo, todo item que é montado, depois disso NUNCA sera usado para montar outro item, entao poderiamos chama-lo de produto final, e os itens de materia prima.

Deu pra entender :?: :? [/quote]

Fred,

Legal o teu ponto de vista, mas um item que a empresa fabrica pode ser usado para fabricar outro item.

Ex: A empresa pode fabricar bicicleta e pneu de bicicleta. Vc concorda que eu posso usar esse mesmo pneu em um monociclo? (aquelas bicicleta de circo que só tem uma roda e 1 asento).

Não da pra tratar um pneu como materia prima, pq hora ele pode se comportar como materia prima(da bicicleta) e hora como produto final(um pneu que é composto de roda e camera, que são efetivamente materias primas de pneu).

vlw![/quote]

Claro, e esta foi a ressalva que fiz: “A nao ser que a empresa fabrique tudo do zero”.

Levei em consideracao que a empresa poderia apenas estar montando as peças, mas caso ela fabrique desde o pneu ai ja muda de cenario claro.
Neste caso acho que teu relacionamento esta correto.

Agora tambem fiquei na duvida de como ficaria a qtde nas classes.

Tentei reproduzir o exemplo aqui e mandar o Netbeans gerar as Entity classes pra mim, mas ele simplesmente nao faz o many-to-many se a tabela de ligação tiver outros campos que nao sejam apenas as FK das tabelas, neste caso ele cria a entity itens_itens e faz many-to-one dela pra outras.
Um cara fala disso aqui: http://forums.netbeans.org/ntopic3253.html

Mais duvidas:

A solução da classe do fantomas resolve o problema de subitens? :
Ex:
->Item Bicicleta
---------->Item pneu
------------------->Item roda
------------------->Item camera

[code]

  1. public class Item {
  2. private List itens = new ArrayList(0);
  3. // Outros atributos
  4. // Métodos
  5. } [/code]
    O meu orientador indicou o seguinte relacionamento de classes:

[code]Class Item{
ListaDeItens lista;
}

Class ListaDeItens{
Item[] Itens;
}[/code]

Achei desnecessario criar uma classe chamada ListaDeItens. Ela resolve o problema da qtd ou realmente é desnecessario?

As classes devem representar tbm a qtd. Ex:

->Item Bicicleta
---------->Item pneu - qtde 2
------------------->Item roda - qtde 1
------------------->Item camera - qtde 1

Vlw!

robisonsilvar segue abaixo um teste para ver se antende o seu caso.

[code]public class Item {
private List subItens = new ArrayList(0);
private String description = null;
private int quantity = 0;

public Item(String description, int quantity) {
	this.description = description;
	this.quantity = quantity;
}

public void addItem(Item item) {
	this.subItens.add(item);
}

public String getDescription() {
	return this.description;
}

public int getQuantity() {
	return this.quantity;
}

public int count() {
	return this.subItens.size();
}

public static void main(String... args) {
	Item bicicleta = new Item("Bicicleta", 1);
	Item pneu = new Item("Pneu", 1);
	Item roda = new Item("Roda", 2);
	Item camera = new Item("Camera", 1);
	
	pneu.addItem(camera);
	roda.addItem(pneu);
	bicicleta.addItem(roda);
}

}[/code]

fwls

[quote=fantomas]robisonsilvar segue abaixo um teste para ver se antende o seu caso.

[code]public class Item {
private List subItens = new ArrayList(0);
private String description = null;
private int quantity = 0;

public Item(String description, int quantity) {
	this.description = description;
	this.quantity = quantity;
}

public void addItem(Item item) {
	this.subItens.add(item);
}

public String getDescription() {
	return this.description;
}

public int getQuantity() {
	return this.quantity;
}

public int count() {
	return this.subItens.size();
}

public static void main(String... args) {
	Item bicicleta = new Item("Bicicleta", 1);
	Item pneu = new Item("Pneu", 1);
	Item roda = new Item("Roda", 2);
	Item camera = new Item("Camera", 1);
	
	pneu.addItem(camera);
	roda.addItem(pneu);
	bicicleta.addItem(roda);
}

}[/code]

fwls[/quote]

Fantomas,
Acho que essa é uma solução.

Uma coisa que eu pensei aqui… Eu acho que a quantity não é uma propriedade do objeto Item, o objeto por si proprio não precisa ter uma qtde para existir, ele precisa ter seu nome e descrição pra existir.

Creio que sua solução esteja certa ignorando o paragrafo acima, pois no seu caso, a propriedade quantity refere-se a quantidade desse item que o pai precisa ter para construi-lo, certo?

abraços!

[quote=robsonsilvar]Uma coisa que eu pensei aqui… Eu acho que a quantity não é uma propriedade do objeto Item, o objeto por si proprio não precisa ter uma qtde para existir, ele precisa ter seu nome e descrição pra existir.

Creio que sua solução esteja certa ignorando o paragrafo acima, pois no seu caso, a propriedade quantity refere-se a quantidade desse item que o pai precisa ter para construi-lo, certo? [/quote]

É verdade, concordo com vc. Um item não precisa da quantidade para existir. Porque o número de itens na lista já oferece esta informação.

Fiz desta maneira para ficar mais próximo o exemplo que vc havia passado; o objetivo principal foi mostrar o uso das associações. Sem conhecer o contexto em detalhes fica difícil determinar a estrutura ideal do objeto.

Essa idéia funciona, mas sugere um algoritmo mais complexo; no caso o algoritmo com fluxo recursivo. A outra idéia seria fazer classes que representa as tabelas do banco de dados, fica mais simples de lêr a estrutura mas fica bem longe de ser OO. Como sempre é uma questão de escolha, onde estarão envolvidos vantagens e desvantagens.

[]'s

[quote=fantomas]É verdade, concordo com vc. Um item não precisa da quantidade para existir. Porque o número de itens na lista já oferece esta informação.
[/quote]
Na verdade, eu acho que sem essa “gambiarra” de colocar a propriedade quantity pra se refenciar a quantidade que o pai precisa deste item(filho), não tem como dizer que um item possui um outro item na quantidade X.

Ex.: Sem a propriedade quantity, não da pra dizer que um item bicicleta possui um item roda na qtde 2, oque sabemos é que um item bicicleta possui uma propriedade chamada subItens, e que nessa propriedade possui uma lista, que possui um objeto do tipo item, que é uma roda. Nós temos a roda, representando uma unica instancia(assim como no MER), mas nao a quantidade dela. :frowning:

[quote=fantomas]
A outra idéia seria fazer classes que representa as tabelas do banco de dados, fica mais simples de lêr a estrutura mas fica bem longe de ser OO. Como sempre é uma questão de escolha, onde estarão envolvidos vantagens e desvantagens. [/quote]
Essa ideia parece ser mais simples(mesmo pq,queriamos utilizar o hibernate). No caso eu continuaria tendo uma classe item, somente com as propriedades nome e descrição e teriamos uma segunda classe chamada ItemComposicao, mas, oque teriamos nessa classe?
(lembrando que a tabela itemComposicao ja esta consolidado)

Se nao for abusar muito, quais são as vantagens e desvantagens de mapear uma classe a um objeto ou fazer a classe pensando puramente OO?

vlw!

[quote=robsonsilvar]
…[/quote]

Estive dando uma olhada em como fazem para Venda => Itens venda.

O que encontrei é que usam 3 classes.

Venda
Item
Produto

Onde uma venda tem 1…N Itens
Um item tem 1…1 Produto

A classe item entao teria

class Item{
    Produto prod;
    int quantidade;
    ...
}

e a venda

class Venda {
    List<Item> itensVenda;
}

Achei uns 3 exemplos fazendo assim, parece ser o consenso. Só to achando estranho o mapeamento para o modelo relacional.
Eu nunca tive duvida com relação ao modelo relacional, la seria com certeza: Venda M…N Produtos, onde surge a tabela linkando os dois, se nao houvesse quantidade, entao estaria ok, voce teria um @ManyToMany no seu entity normal, mas com a quantidade nesta tabela link, ai lasca tudo. Como no exemplo que dei acima no maximo temos um @OneToMany.
Acho que só implementando pra ter uma visao melhor. E como seria feito o mapeamento OR neste caso.
Depois vou procurar em casa, acho que tenho um auto relacionamento M…N, só nao sei se tem algo mais alem das PK, na epoca fiz com Hibernate mapeando em XML ainda, acho que tenho algo la, e entao veriamos como fica com JPA.

PS. estou usando VendaxProduto pra nao confundir, pq no teu caso é tudo Item, mas no final é tudo a mesma coisa, ou seja um relacionamento M…N.

Não sei se entendi as perguntas, mas vamos lá.

Na minha opinião utilizar mapeamentos é vantajoso porque você pode fazer com que o seu sistema fique mais orientado a objetos, a desvantagem é que isso muitas vezes oferece pontos de complexidade, bom seria se utilizassemos banco de dados OO assim não precisariamos utlizar mapeamentos; seria mais natural.

Neste link http://wpjr2.wordpress.com/2008/04/23/orientacao-por-objetos-vantagens-e-desvantagens/ tem um texto que fala sobre vantagens e desvantagens da OO. Talvez ajude a entender mais detalhes.

[]

[quote=fredferrao][quote=robsonsilvar]
…[/quote]

Estive dando uma olhada em como fazem para Venda => Itens venda.

O que encontrei é que usam 3 classes.

Venda
Item
Produto

Onde uma venda tem 1…N Itens
Um item tem 1…1 Produto

A classe item entao teria

class Item{
    Produto prod;
    int quantidade;
    ...
}

e a venda

class Venda {
    List<Item> itensVenda;
}

Achei uns 3 exemplos fazendo assim, parece ser o consenso. Só to achando estranho o mapeamento para o modelo relacional.
Eu nunca tive duvida com relação ao modelo relacional, la seria com certeza: Venda M…N Produtos, onde surge a tabela linkando os dois, se nao houvesse quantidade, entao estaria ok, voce teria um @ManyToMany no seu entity normal, mas com a quantidade nesta tabela link, ai lasca tudo. Como no exemplo que dei acima no maximo temos um @OneToMany.
Acho que só implementando pra ter uma visao melhor. E como seria feito o mapeamento OR neste caso.
Depois vou procurar em casa, acho que tenho um auto relacionamento M…N, só nao sei se tem algo mais alem das PK, na epoca fiz com Hibernate mapeando em XML ainda, acho que tenho algo la, e entao veriamos como fica com JPA.

PS. estou usando VendaxProduto pra nao confundir, pq no teu caso é tudo Item, mas no final é tudo a mesma coisa, ou seja um relacionamento M…N.[/quote]

Blz, Vamos ver se vc consegue resolver esse enigma :roll:

vlw até aqui!

Pessoal, contornamos o problema da seguinte forma, vejam como ficou e digam oque acham baseado no entendimento do problema que tentei passar ao longo deste post:

[code]
public class Item {

private int idItem;
private String nomeItem;
private List<Material> materiais = new ArrayList<Material>(0);	

public Item(int id, String nome){
	this.idItem = id;
	this.nomeItem = nome;		
}
public int getIdItem() {
	return idItem;
}
public void setIdItem(int idItem) {
	this.idItem = idItem;
}
public String getNomeItem() {
	return nomeItem;
}
public void setNomeItem(String nomeItem) {
	this.nomeItem = nomeItem;
}
public void setMateriais(List<Material> materiais) {
	this.materiais = materiais;
}
public List<Material> getMateriais() {
	return materiais;
}

}

public class Material {
private Item itemInsumo;
private int qtd;

public Material(Item i,int qtd){
	this.itemInsumo = i;	 
	this.qtd = qtd;
}
public Item getItemInsumo() {
	return itemInsumo;
}
public void setItemInsumo(Item itemInsumo) {
	this.itemInsumo = itemInsumo;
}
public int getQtd() {
	return qtd;
}
public void setQtd(int qtd) {
	this.qtd = qtd;
}

}[/code]

abraços!

O que o robsonsilvar realmente quer é elabora parte de um ERP, a composição de produtos.

O DER do robsonsilvar está perfeito.

Trabalhei em um projeto de ERP e o que fizermo foi exatamente criar a classe Item e a classe ItemComposto.

Para modelar você terá que usar Classe Associativa!

UML2 Guia Prático - Gilleanes T. A. Guedes
ou
UML2 - Gilleanes T. A. Guedes

Esperto ter ajudado!

abc