originalmente publicado em http://50minutos.com.br/blog

Definição:

É um padrão que nos permite tratar de forma igual objetos simples e objetos compostos (formados por outros objetos).

Quando usar:

  • Quando você tem uma estrutura irregular de objetos simples e compostos (pais e filhos, pastas e arquivos, por exemplo);
  • Quando você quer tratar os objetos simples e os compostos da mesma forma.
padrão composite

Como usar:

  • Criar uma classe Component que implemente IComponent;
  • Criar uma classe Composite que implemente IComponent;
  • Adicionar um campo privado (list) do tipo coleção de IComponent;
  • Adicionar um construtor que inicialize a coleção;
  • Implementar Operation de modo que ele execute Operation de cada elemento de list.

Exemplo:



using System;
using System.Collections.Generic;


namespace _50minutos_composite
{
    class Program
    {
        static void Main(string[] args)
        {
            IObjeto arq1 = new Arquivo("composite.png");
            IObjeto arq2 = new Arquivo("minhaFoto.gif");
            IObjeto arq3 = new Arquivo("curriculum.docx");


            IObjeto pastaPrincipal = new Pasta("arquivos");
            IObjeto pasta1 = new Pasta("imagens");
            IObjeto pasta2 = new Pasta("office");


            pastaPrincipal.Adicionar(pasta1);
            pastaPrincipal.Adicionar(pasta2);


            pasta1.Adicionar(arq1);
            pasta1.Adicionar(arq2);


            pasta2.Adicionar(arq3);
            pasta2.Adicionar(new Arquivo("composite.pdf"));


            Console.WriteLine(pastaPrincipal);


            Console.ReadKey();
        }
    }


    //IComponent
    interface IObjeto
    {
        String Nome { get; set; }
        int Nivel { get; set; }
       
        // Operation
        void Adicionar(IObjeto o);
    }


    //Component (ou Leaf)
    class Arquivo : IObjeto
    {
        public String Nome { get; set; }
        public int Nivel { get; set; }


        public Arquivo(String nome)
        {
            this.Nome = nome;
        }


        //Operation
        public void Adicionar(IObjeto o)
        {
            Console.Write("não permitido");
        }


        //Operation
        public override string ToString()
        {
            return String.Format("{0}{1}\n",
                new String(' ', this.Nivel),
                this.Nome);
        }
    }


    //Composite
    class Pasta : IObjeto
    {
        //list : IComponent
        List conteudo;


        public String Nome { get; set; }
        public int Nivel { get; set; }


        public Pasta(String nome)
        {
            this.Nome = nome;
            this.conteudo = new List();
        }


        //Operation
        public void Adicionar(IObjeto o)
        {
            o.Nivel = this.Nivel + 3;
            this.conteudo.Add(o);
        }


        //Operation
        public override string ToString()
        {
            String retorno = String.Format("{0}{1}\n",
                new String(' ', this.Nivel),
                this.Nome);


            foreach (var item in this.conteudo)
            {
                retorno += item;
            }


            return retorno;
        }
    }
}