Design Patterns: Composite em Ruby

Posted on October 27, 2009

2


A idéia de componentes sendo construídos a partir de “sub componentes” é algo bem comum em um software. Construir objetos a partir de “sub objetos” é o que sugere o padrão Composite, ou seja, objetos simples se integrando para resultar em um mais complexo e interessante para o sistema.

Vamos pegar um exemplo:

composite

Contruir um Copo de suco é uma composição de uma série de tarefas.
Uma dos pontos positivos aqui é que qualquer objeto do sistema que precisar do CopoDeSuco não precisa se preocupar com a complexidade da criação desse objeto.
ingredientes

Show me the code!

O GoF chama essa situação de “the sum acts like one of the parts”. Primeiro precisamos de uma interface comum aos objetos. Essa interface é chamada de component.

Cada tarefa “indivisível” do processo é chamada de leaf. Cada um desses objetos deve implementar a interface acima.

O Composite, enfim, é o componente no nível mais alto da hierarquia.

Picture 1

Nossa tarefa tem apenas um initialize e uma método “duracao”. Obviamente poderia ter muitas outras características.

Vamos a criação das tarefas:

Picture 2

AdicionarIngredientes e Mistura são dois leafs, ou seja, duas tarefas que não dividimos nesse modelo. Vamos criar um component a partir desses objetos.

O objeto Suco é o resultado dessa composição. Ao criarmos esse componente, precisamos de um array de sub tarefas. Criaremos os métodos que adicionam e removem essas sub tarefas.

Picture 3

Para evitar duplicação de código, vamos extrair um component e criaremos a classe Composite.

Picture 4

Aplicando a mesma lógica agora temos a classe Suco da seguinte forma:

Picture 5

E aplicamos a mesma idéia a classe CopoDeSuco. Essa classe é uma composição entre um component e um leaf.

Picture 6

Nossa classe composite poderia ter herdado diretamente de Array para receber os métodos que precisamos, porém essa seria uma implementação estranha. Um composite não é um tipo “especializado” de array, e estariamos utilizando a herança apenas por preguiça fazendo isso.

suco

Posted in: oo, ruby