Difference between revisions of "Composite (padrão de desenho)/Exemplo 1: Empregada de Restaurante"

From Wiki**3

< Composite (padrão de desenho)
Line 4: Line 4:
 
Uma implementação simples definiria na implementação do conceito ''empregada'' as referências para os objectos que representam as ementas.
 
Uma implementação simples definiria na implementação do conceito ''empregada'' as referências para os objectos que representam as ementas.
  
<java5>
+
<source lang="java">
 
public class Empregada0 {
 
public class Empregada0 {
 
   
 
   
Line 28: Line 28:
 
     }
 
     }
 
   }
 
   }
</java5>
+
</source>
  
 
Esta situação conduz a inflexibilidade na manutenção: por exemplo, a adição de novas refeições implica a alteração das empregadas!
 
Esta situação conduz a inflexibilidade na manutenção: por exemplo, a adição de novas refeições implica a alteração das empregadas!

Revision as of 01:42, 8 November 2018

Um restaurante tem empregadas que apresentam menus aos clientes. Cada empregada dispõe de várias ementas, consoante a hora do dia: assim, existem ementas para pequenos almoços, almoços e jantares, por exemplo.

A Empregada Básica

Uma implementação simples definiria na implementação do conceito empregada as referências para os objectos que representam as ementas.

public class Empregada0 {
 
  Ementa _ementaPequenoAlmoço;
  Ementa _ementaAlmoço;
  Ementa _ementaLanche;
 
  public Empregada0(Ementa ementaPequenoAlmoço, Ementa ementaAlmoço, Ementa ementaLanche) {
    _ementaPequenoAlmoço = ementaPequenoAlmoço;
    _ementaAlmoço = ementaAlmoço;
    _ementaLanche = ementaLanche;
  }
 
  public void printMenu() {
    printMenu(_ementaAlmoço);
    printMenu(_ementaLanche);
  }
 
  public void printMenu(Ementa ementa) {
    System.out.println(ementa.nome());
      for (ItemEmenta item : ementa)
        System.out.printf("%s, %s%n    -- %s%n", item.nome(), item.preço(), item.descrição());
    }
  }

Esta situação conduz a inflexibilidade na manutenção: por exemplo, a adição de novas refeições implica a alteração das empregadas!

Refeições a todas as horas

Uma possível solução é definir as empregadas como tendo, não dois, três, ou um número concreto de ementas, mas sim como tendo a capacidade de gerir um número indeterminado (uma colecção) de ementas.

 import java.util.ArrayList;

 public class Empregada1 {

   ArrayList<Ementa> _ementas;

   public Empregada1(ArrayList<Ementa> ementas) {
     _ementas = ementas;
   }

   public void printMenu() {
     for (Ementa ementa : _ementas) printMenu(ementa);
   }

   public void printMenu(Ementa ementa) {
     System.out.println(ementa.nome());
     for (ItemEmenta item : ementa)
       System.out.printf("%s, %s%n    -- %s%n", item.nome(),
                         item.preço(), item.descrição());
   }

 }

Sobremesas ao Jantar

Mas o que aconteceria se se quisesse adicionar uma outra ementa apenas a uma das refeições? Por exemplo, adicionar uma ementa de sobremesas ou uma carta de vinhos à ementa do jantar. A solução anterior não tem limitações ao número de ementas que uma empregada pode gerir. No entanto, adicionar uma ementa à colecção não a associa de forma alguma à ementa do jantar: seria necessário alterar o código da empregada para fazer tal associação: uma situação indesejável. A solução passa por utilizar o padrão de composição (composite): por um lado a ementa do jantar vai ter uma outra ementa como se fosse mais uma entrada, por outro a empregada trata a ementa do jantar como sempre fez (i.e., sem alterações).

 public abstract class ComponenteEmenta {  

   public void adicionar(ComponenteEmenta componente) {  
     throw new UnsupportedOperationException();  
   }  

   public ComponenteEmenta obtémFilho(int i) {  
     throw new UnsupportedOperationException();  
   }  

   public String nome() {  
     throw new UnsupportedOperationException();  
   }
  
   public String descrição() {  
     throw new UnsupportedOperationException();  
   }  

   public double preço() {  
     throw new UnsupportedOperationException();  
   }  

   public boolean vegetariano() {  
     throw new UnsupportedOperationException();  
   }  

   public void print() {  
     throw new UnsupportedOperationException();  
   }  
 }
 public class Ementa extends ComponenteEmenta {  
     ArrayList<ComponenteEmenta> _componentes = new ArrayList<ComponenteEmenta>();  
     String _nome;  
     String _descrição;  
   
     public Ementa(String nome, String descrição) {  
         _nome = nome;  
         _descrição = descrição;  
     }  
   
     public void adicionar(ComponenteEmenta componente) {  
         _componentes.add(componente);  
     }  
   
     public ComponenteEmenta obtémFilho(int i) {  
         return _componentes.get(i);  
     }  
   
     public String nome() { return _nome; }  
     public String descrição() { return _descrição; }  
   
     public void print() {  
         System.out.printf("%n%s, %s%n", nome(), descrição());  
         System.out.println("--------------------");  
         for (ComponenteEmenta componente : _componentes)  
             componente.print();  
     }  
 } 
 public class ItemEmenta extends ComponenteEmenta {  

     String _nome;  
     String _descrição;  
     boolean _vegetariano;  
     double _preço;  

     public ItemEmenta(String nome, String descrição, boolean vegetariano, double preço) {  
         _nome = nome;  
         _descrição = descrição;  
         _vegetariano = vegetariano;  
         _preço = preço;  
     }  

     public String nome() { return _nome; }  
     public String descrição() { return _descrição; }  
     public double preço() { return _preço; }  
     public boolean vegetariano() { return _vegetariano; }  

     public void print() {  
         System.out.print(nome());  
         if (vegetariano()) System.out.print(" (v)");  
         System.out.println(", " + preço());  
         System.out.println("    -- " + descrição());  
     }  
 }
 public class Empregada2 {  
   private ComponenteEmenta _ementas;  
   public Empregada2(ComponenteEmenta ementas) { _ementas = ementas; }  
   public void printMenu() { _ementas.print(); }  
 }
 public class Restaurante {  
   public static void main(String[] args) {  
     ComponenteEmenta pequenoAlmoço = new Ementa("PEQUENO ALMOÇO", "Pequeno Almoço");  
     ComponenteEmenta almoço        = new Ementa("ALMOÇO", "Almoço");  
     ComponenteEmenta lanche        = new Ementa("LANCHE", "Lanche");  
     ComponenteEmenta jantar        = new Ementa("JANTAR", "Jantar");  
     ComponenteEmenta sobremesas    = new Ementa("SOBREMESAS", "Hmmmm!");  

     ComponenteEmenta refeições = new Ementa("REFEIÇÕES", "Tudo!");  

     refeições.adicionar(pequenoAlmoço);  
     refeições.adicionar(almoço);  
     refeições.adicionar(lanche);  
     refeições.adicionar(jantar);  

     jantar.adicionar(new ItemEmenta("Esparguete", "Esparguete com deliciosas alcaparras",  
                                     true, 5.49));  
     jantar.adicionar(sobremesas);  

     Empregada2 empregada = new Empregada2(refeições);  
     empregada.printMenu();  
   }  
 }