none
Montando árvores com objetos e coleções diferentes

    Question

  • Oi Pessoal,

    Tenho o seguinte problema:

    Possuo 5 classes que formam como uma árvore, seguem uma hierarquia.
    Para fazer o controle tenho uma propriedade com a classe Pai e uma propriedade que é coleção de objetos filhos.

    A questão é, formo 3 tipos de "árvores" diferentes com esses objetos, seguindo hierarquias diferentes como por exemplo:

    A,B,C,D,E são as classes
    Arvore 1:     A - B - C - D - E
    Arvore 2:     A - D - E - B - C
    Arvore 3:     A - C - B - D - E

    Estou criando uma classe para gerenciar a formação das "árvores". Se a árvore fosse só do tipo 1, a partir da classe A, criava uma coleção de objetos B e da B criava uma coleção de C, e assim por diante. Porém quando a ordem mudar, como farei iso?
    Tendo ordens diferentes, como posso gerenciar isso? Pensei em usar enumeradores com a ordem de cada um, mas não sei como instanciar um objeto de determinado tipo sem tê-lo diretamente no código.

    Preciso de algo dinâmico para criar objetos da classe que irei usar, dependendo do tipo de árvore.

    Obrigado desde já pela ajuda.
    Wednesday, May 09, 2007 12:54 PM

All replies

  • Paulo,

     

    Você poderia criar uma classe base padrão para todas, assim todas as classes A,B,C,D e E herdariam de um tipo em comum e você poderia definir as coleções nas classes baseados nesse tipo comum.

    Outra possibilidade seria fazer uma Interface, e todas as classes implementariam tal interface. Suas coleções seriam do tipo da Interface.

     

    Quais os tipos de filhos uma classe vai poder obter é uma regra de negócio. Você teria que implementar um método em específico para receber os itens filhos para cada classe. Na hora de analisar se o objeto pode ser filho ou não você aplica a regra. Por exemplo, pelo que você passou, a classe B só pode ser pai de um objeto C ou D. E só pode ser pai de D se a instância de B no caso for filha de C também. Ou seja, cada objeto teria que conhecer seu pai também para ver se pode aceitar outros como filho.

     

    Algo nesse sentido....

     

    Abraços,
    Francisco
    OK, Computer - http://thespoke.net/blogs/fbcjunior/default.aspx

     

     

    Wednesday, May 09, 2007 1:03 PM
    Moderator
  • Obrigado Francisco...
    pelo que havia lido, surgiu-me a idéia de usar interface, mas não usei por falta de experiência de trabalho com interfaces

    Na realidade a arvoré é bem genérica.
    Uma classe B, pode ter filhos C, D ou E..  e assim para todas as outras.
    Isso só altera a forma de visualização como forma de relatório.. como um sistema de transportadora.
    Supondo A como 1 dia de programação, B como rotas e C como motoristas..
    se faço A-B-C , visualizo Programação - Rotas disponiveis - Motoristas por rota
    se faço A-C-B , visualizo Programação - Motoristas - Rotas por motoristas

    O pai eu vou saber pois já instanciei antes de criar a coleção filha.

    As minhas classes herdam uma classe base, mas não uso interfaces.
    Pode me dar um exemplo (mesmo em pseudocodigo) de como instanciar a criação da coleção filha usando a interface, e sendo "genérico" podendo criar coleção de B, ou C, a partir de A
    Wednesday, May 09, 2007 1:28 PM
  • Paulo,

     

    Então, por exemplo, você poderia criar uma interface mais ou menos assim:

     

    using System;

    using System.Collections.Generic;

    using System.Text;

    namespace WindowsApplication1

    {

    // Vamos dizer que todo mundo que puder ser filho de alguma classe

    // tenha obrigatoriamente que assinar esta interface...

    public interface IFilho

    {

         // ... e que esta interface obrigue todo mundo que quiser a assina-la

         // disponha de uma propriedade que indique quem é o pai.

         IPai Pai

         {

              get;

              set;

         }

    }

    // Vamos dizer que para alguém ser Pai de alguma classe, ele tem que

    // implementar esta interface

    public interface IPai

    {

         // ... e que todo pai tem que ter uma coleção de filhos...

         List<IFilho> Filhos

         {

              get;

         }

         // ... e implementar um método para adicionar filhos...

         void AddFilho(IFilho filho);

    }

    // Vamos dizer que a classe A só pode ser Pai

    public class A : IPai

    {

         private List<IFilho> filhos = new List<IFilho>();

         public List<IFilho> Filhos

         {

              get { return filhos; }

         }

         public void AddFilho(IFilho filho)

         {

              // Vamos dizer que A pode ser pai de B ou C em qualquer

              // circunstância, então não vou testar nada.

              filho.Pai = this;

              filhos.Add(filho);

         }

    }

    // Agora, vamos dizer que B pode ser pai e filho

    public class B : IPai, IFilho

    {

         IPai pai;

         List<IFilho> filhos = new List<IFilho>();

         public List<IFilho> Filhos

         {

              get { return filhos; }

         }

         public void AddFilho(IFilho filho)

         {

              // Vamos dizer que B pode ser pai de C,

              // mas não de outro B.

              if (filho is C)

              {

                   filho.Pai = this;

                   filhos.Add(filho);

              }

              else

              {

                   throw new Exception("Filho inválido");

              }

         }

         public IPai Pai

         {

              get{ return pai; }

              set{ pai = value;}

         }

    }

    // C vai ser igual a B, exceto...

    public class C : IPai, IFilho

    {

         IPai pai;

         List<IFilho> filhos = new List<IFilho>();

         public List<IFilho> Filhos

         {

              get { return filhos; }

         }

         public void AddFilho(IFilho filho)

         {

              // ... que vamos dizer que ele pode ser

              // pai de qualquer B

              if (filho is B)

              {

                   filho.Pai = this;

                   filhos.Add(filho);

              }

              else

              {

                   throw new Exception("Filho inválido");

              }

         }

         public IPai Pai

         {

              get { return pai; }

              set { pai = value; }

         }

    }

    }

     

    Aí, para testar :

     

    // vou criar uma instância de a...

    A a = new A();

    // ... vou criar um filho b para ele...

    B b = new B();

    // ... e um c também...

    C c = new C();

    a.AddFilho(b);

    a.AddFilho(c);

    // Vou criar um C para ser filho de b;

    C cFilho = new C();

    b.AddFilho(cFilho);

    // ... e um B para ser filho de c;

    B bfilho = new B();

    c.AddFilho(bfilho);

    // Aí eu posso percorrer os filhos normalmente

    foreach (IFilho f in a.Filhos)

    {

         Console.WriteLine(f.ToString());

         // se o filho for pai também...

         if (f is IPai)

         {

              IPai pai = f as IPai;

              foreach (IFilho f1 in pai.Filhos)

              {

                   Console.WriteLine(f.ToString());

                   // o ideal seria algo recursivo aqui, na verdade

              }

         }

    }

     

    Sugiro que você vá debugando pela execução do código para melhor entendimento.

     

    Abraços,
    Francisco
    OK, Computer - http://thespoke.net/blogs/fbcjunior/default.aspx

     

    Wednesday, May 09, 2007 2:00 PM
    Moderator