none
Qual a melhor maneira de fazer criar uma classe

    General discussion

  • Olá a todos, sou iniciante em C# e estou com uma dúvida. Imaginem que tenho uma tabela chamada (Clientes) com os campos (CodigoCliente, Nome, Telefone) e que tenho uma tabela (Pedidos) com os campos (CodigoPedido, CodigoCliente, Data, Status). Este é apenas um exemplo que ocorre em muitas situações, no exemplo há um relacionamento de 1 para n, ou seja, um cliente pode ter vários pedidos, minha dúvida é qual a melhor forma de implementar a classe (Pedido).

    Assim?
    public class Pedido{
       private int codigoPedido;
       private int codigoCliente;
       private DateTime data;
       private bool status;
    
       // contrutor
       public Pedido(){
          ...
          ...
       }
    
       // get, set
       ...
       ...
    }
    Ou assim:
    public class Pedido{
       private int codigoPedido;
       private Cliente cliente;
       private DateTime data;
       private bool status;
    
       // contrutor
       public Pedido(){
          ...
          ...
       }
    
       // get, set
       ...
       ...
    }
    Na primeira opção o mapeamento foi feito exatamente como na tabela no banco de dados, já na segunda opção foi declarado uma variável do tipo Cliente. Gostaria da opinião de programadores mais experientes.

    Agradeço a todos que puderem colaborar.
    Monday, August 03, 2009 8:32 PM

All replies

  • Bem quando se trata de boas praticas de OO, vc usar a segunda opção... passe a classe e nao o codigo, pq... toda vez que vc prescisa de uma informação do cliente no seu pedido vc vai ter que gerar um processamento para carregar os dados do mesmo...

    exemplo...

    digamos q vc faça do metodo 1:

    vc carrega numa grid a lista de pedidos feitos em uma data, quando o usuario da um duplo clique na linha abre um tela com os dados do cliente... ate ai tudo ok...
    tempos depois teu cliente pede para que apareça o nome do cliente na grid junto com o pedido... pois eh... para cada linha da sua grid vc vai ter q carregar a classe cliente, e quando der o duplo clique ao inves de vc ja usar o cliente instanciado teria q instacia outra classe cliente pq vc so tem o codigo dele....

    entao por definição... sempre q puder usar a classe inteira como propriedade a use....

    porem....

    tome cuidado em casos q vc usa web services... pq vc pode ter a seguinte situacao:

    class Pedido {
          public Cliente cliente;
    }

    class Cliente {
         public Pedido[] pedidos;
    }

    bem... na hora de serializar isso vai ser meio complicado..... a forma de arrumar é:

    class Pedido {
          public Cliente cliente;
    }

    class Cliente {
         internal Pedido[] pedidos;
    }

    pq vc serializa so os clientes dos pedidos, mas nao seraliza os pedidos do cliente...
    What would Brian Boitano do ?
    Monday, August 03, 2009 9:14 PM
  • Essa pergunta vai dar bastante discussão...

    Eu particularmente gosto da abordagem de manter para efeito de persistência a classe com a mesma representação da base de dados. Isso simplifica muito a camada de acesso a dados.

    Já na camada de negócio, eu gosto de usar a primeira opção que você deu, ou seja, fazer referências aos demais objetos.

    Eu gosto de trabalhar dessa forma, pq torna a aplicação mais independente de como foi escrita a camada de acesso a dados, evitando referências circulares como no exemplo citado pelo Rui.

    Um pouco dessa abordagem, você pode encontrar aqui:



    Abraço,

    Eric
    Tuesday, August 04, 2009 11:42 AM
  • CSharpando,

    Particularmente prefiro implementar como o Eric comentou, mas a solução do Rui também é válida.

    Você já pensou em utilizar o ADO.NET Entity Framework ou até mesmo DataSets tipados ?

    Efficient Coding With Strongly Typed DataSets
    http://msdn.microsoft.com/en-us/magazine/cc163877.aspx

    The ADO.NET Entity Framework Overview
    http://msdn.microsoft.com/en-us/library/aa697427(VS.80).aspx

    Att.

    Ari C. Raimundo
    Tuesday, August 04, 2009 1:24 PM
  • Antes de tudo quero agradecer as respostas, não imaginei que alguém fosse responder tão rápido. Obrigado Rui, Eric e Ari.

    Vocês já me deram algumas idéias, realmente é uma dúvida cruel, ambos os modos tem seus prós e contras, manter todos os objetos igual as tabelas no banco de dados ajuda muito na camada de acesso a dados, mas dificulta muito na camada de negócio. Já o contrário dificulta na camada de acesso a dados mas melhora muito a camada de negócio.

    Eu cheguei a pensar em criar classes para serem utilizadas só na camada de acessoa a dados, todas iguais as tabelas, e criar classes só para a camada de negócios, só que acho que ficaria confuso e muitas classes poderiam até ficar iguais.

    Eu acho utilizar uma classe é melhor do que somente o código.

    Como disse sou iniciante em C#, estou gostando muito da linguagem, já li bastante sobre a linguagem em si e sobre orientação a objetos e também aplicações em camadas.

    A camada de acesso a dados até que está tranquilo. A de negócio complica mais um pouco mas está indo. Agora a interface com o usuário que eu achei que seria a mais fácil, está sendo a pior de todas, principalmente quando estou em uma tela que no banco irá acessar duas tabelas e este tem uma relação de 1 para n. Imaginem o Pedido, no banco a tabela Pedidos tem CodigoPedido como chave primária e este campo é auto-numerado, ou seja, quando eu incluo um novo pedido ele gera o valor automaticamente, aí tenho uma tabela ItensPedido que tem como chave primária o conjunto dos campos CodigoPedido e CodigoItem, ambos os campos são chaves estrangeiras. A tela que imaginei foi, os dados do pedido é inserido em textbox e outros controles, já os itens do pedido é inserido em um datagridview, na teoria tudo beleza, mas na prática é fogo, acontece vários problemas e meu código está ficando muito sujo, acho que estou cometendo o erro de implementar as regras de negócio nos códigos da interface. Para a tela de pedido pensei em implementar uma tela auxiliar para adicionar os itens, como se fosse uma pesquisa que o usuário digita parte do nome do item, vê uma lista de resultados, seleciona um item e adiciona ao pedido, mas na prática estou quebrando a cabeça.

    Mas voltando a discussão de como implementar as classes, foi sugerido o uso de datasets, eu até vi um webcast não me lembro o nome do palestrante, que falou sobre agilidade em criar aplicações simples com o uso de datasets para a criação dos objetos, mas eu achei muito confuso, principalmente para implementar as regras de negócio e para fazer as validações dos dados. Com classes próprias eu posso realizar umas validações básicas já na hora do set.

    E vendo o comentário de vocês surgiu uma dúvida ainda maior, ainda pensando nas tabelas Pedidos, itensPedido, Produtos, onde temos uma relação de 1 para n entre pedidos e itensPedido, e outra relação de 1 para n entre Produtos e Itens pedido, como ficariam estas classes, A classe pedido teria uma coleção de ItensPedido? A classe Produtos teria uma coleção de Intes Pedido? A classe ItensPedido teria duas coleções uma de Pedidos e outra de Produtos? Nossa tá dando um nó no meu cérebro.

    Realmente realizar o mapeamento de um banco de dados relacional para um modelo orientado a objetos é muito difícil.

    Mas um dia eu chego lá.

    Thursday, August 06, 2009 2:37 PM
  • Hi :)

    Bem existem algumas camadas de Acesso a Dados que podem ser usadas como camadas de negocio com o Linq e o NHibernate...

    na verdade a questao vai mais pelo bom senso... depende da quantidade de acesso as dados no sistema... informaçoes mais usadas vc carrega uma vez so... informacoes menos usadas vc aramazena so o codigo... por ai vai.. depende da necessidade mesmo...

    vc tambem pode usar as 2 tecnicas... criando uma classe de acesso aos dados igual ao banco com propriedades privadas... e implementar propriedades publicas apenas as que sao referentes a sua classe de negocio (tipo... a chave primaria autoincremental pode estar na sua classe como privada... mas ela nao prescisa aparecer na sua classe de negocio)

    Nas relacoens 1 para N tem gente que gosta de usar Collections... outros preferem o IList por ser mais facil de implementar... eu uso arrays mesmo... para ter um controle maior na hora de distribuir meu codigo para outros desenvolvedores...

    "Realmente realizar o mapeamento de um banco de dados relacional para um modelo orientado a objetos é muito difícil"

    é... ja foi um problemao mesmo isso kkkkk alias... quando é que vao lançar um SGBD Orientado a Objetos logo ??? tinha o Cache.. mas faz tempo q nao acompanho mais ele...

    Mas com as frameworks tipo o Linq e o NHibernate que citei assima esse processo ta bem mais facil... da uma olhada nelas...
    What would Brian Boitano do ?
    Thursday, August 06, 2009 7:34 PM
  • Olá Rui, eu estou relutando para entrar no mundo das ferramentas que controlam a persistencia de dados, apesar que confesso que tentador pensar apenas nas classes e deixar que uma ferramenta cuide dos bastidores no banco de dados, no entanto, como você mencionou, ainda não existe um banco de dados orientado a objetos confiável, existem vários projetos por aí, mais ainda não pegou.

    Na empresa que trabalho, foi contratado uma outra empresa para desenvolver um sistema, eles usam C# com banco Oracle, e os famosos componentes da DevExpress, até aí beleza, o banco dispensa comentários, embora por eu não ter muita experiência prefido o sqlserver por achar mais amigável, C# é muito bom, os componentes da DevExpress impressionam pelo visual (as vezes eu me pergundo se estes caras que desenvolvem estes componentes devem ser malucos que ficam o dia todo imaginando tais componentes e não fazem mais nada da vida para conseguirem desenvolver), até aí beleza, mas na hora do vamos ver há um problema, no pacote da dev existe o xpo se não estou enganado, que cuida da persistência de dados, o cara me disse que eles não precisam nem criar as tabelas no banco, ao adicionar uma nova classe no projeto, o próprio xpo gera a tabela no banco, achei fantástico, mas na prática não é tão bom assim, o banco fica repleto de tabelas, e o sistema fica muito lento em algumas consultas devido a quantidade de relacionamentos, aí que fiquei ocm o pé atras.

    Ainda estou fazendo um misto de orientação a objetos na camada de negócios e na camada de dados tento deixar as coisas mais parecidas com o mundo dos bancos relacionais.

    Depois que começei a "brincar com C#' aprendi muita coisa, mas também descobri que quanto mais aprendo, aumenta minha noção do quanto eu ainda tenho que aprender (se é que consegui ser claro).

    Agradeço mais uma vez aos que responderam este tópico.
    Wednesday, August 26, 2009 8:31 PM
  • Ah entendi.... tmb ja fui assim... mas fui ficando velho e preguiçoso.... (mesmo pq ultimamente eu ando mais na parte de planejamento e gerenciamento que nao to muito focado em programaçao....)

    bem antes eu tinha (quer dizer tenho ><) mania de fazer as minhas proprias frameworks... isso é .. sim eu gosto de reiventar a roda mesmo...

    fazer uma framework para acesso a bando de dados nao é tao dificil como parece... so eh meio demorado... mas ...

    bem a prinicipio vc tem q estudar 2 coisas... System.Reflection e criaçao de Atributos de classe e de propriedades... com esses 2 mais um basico de ADO.net vc consegue montar uma camada de acesso a dados customizada para a sua implementaçao...

    e o povo da DevExpress nao tem vida... U.U pergunta pra algum deles qual foi a ultima vez q ele sentou num bar e tomou uma breja kkkkkkkk :P
    What would Brian Boitano do ?
    Wednesday, August 26, 2009 11:13 PM