Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Design Patterns
Code

Padrões de design: O padrão Decorator

by
Difficulty:IntermediateLength:ShortLanguages:
This post is part of a series called Design Patterns in PHP.
Design Patterns: The Adapter Pattern
Design Patterns: The Strategy Pattern

Portuguese (Português) translation by Francisco Sousa (you can also view the original English article)

Previamente nestas séries, exploramos ambos os padrões de design facade e adapter. Usando facade(fachada), nós podemos simplificar grandes sistemas, e através da implementação do adapter, nós podemos manter-nos seguros enquanto trabalhamos com classes de API externas. Agora nós vamos cobrir o padrão de design decorator, o qual também pertence a categoria dos padrões de estrutura.

Nós podemos usar o padrão decorator, quando simplesmente queremos adicionar alguma responsabilidade a nossa classe. Este padrão de design é uma boa alternativa a funcionalidade de subclasses para estender funcionalidade com algumas vantagens adicionais.

Problema

Se estás confuso e pensas que nós podemos alcançar a mesma funcionalidade com a subclasse, deixa-me demonstrar alguns exemplos de código, que irão remover essa confusão e farão adorares o padrão decorator.

Eu vou pegar no exemplo de uma classe a qual é responsável por gerar conteúdo para um email. No próximo bloco de código, como podes ver, esta classe funciona muito bem para gerar conteúdo de email sem qualquer modificação.

Nós sabemos que o Natal está a chegar, e vamos dizer que eu quero agradar ao meu leitor com uma mensagem no próximo email de newsletter. Assim tenho que adicionar uma mensagem no corpo do email com uma imagem que fique bem.

Por causa disto eu posso diretamente editar a minha classe email, o que eu não quero realmente fazer. Assim eu posso implementar herança para alcançar o mesmo efeito. Eu crio uma classe filho separada da classe principal do corpo do email:

Assim, eu tenho o meu código pronto, e após alguns dias, eu quero ler o email com saudações de Novo Ano. Podemos utilizar o mesmo método que fizemos para o Natal.

Isto é feito de forma suave, sem qualquer problemas. Agora vamos dizer que eu esqueci-me de felicitar os meus visitantes nas duas ocasiões (Natal e Ano Novo) e eu quero mandar ambas as felicitações num email, sem modificar qualquer código na classe base. 

A tua mente fica cheia imediatamente, com a seguinte questão: Irá subclasses e herança ajudar? Eu seria a favor de seguir este caminho, mas iriamos necessitar de usar extra/desnecessário código para alcançar isto. Podemos usar traits que nos permite implementar algo semelhante a múltipla herança.

Solução

O problema que discutimos na secção anterior pode ser resolvido através da implementação do padrão decorator. 

De acordo com aWikipedia:

O padrão decorator (também conhecido por wrapper, uma alternativa de nome partilhada com o padrão Adapter), o qual é um padrão de design que permite a adição de comportamento a um objeto individual, tanto estaticamente ou dinamicamente, sem afetar o comportamento de outros objetos da mesma classe.

Na secção acima nós vimos que podemos estender funcionalidades/comportamento usando uma subclasse, mas quando se trata de adicionar múltiplas funcionalidades/comportamentos, torna-se complexo e demorado. É nestes casos que devemos utilizar o padrão decorator.

Interface

Esta é uma simples interface para ter a certeza que qualquer classe tem que implementar os métodos necessários. 

Classe principal email

Esta é a classe principal a qual está a gerar o corpo por defeito de um email, o qual é geralmente usado para enviar emails. O que necessitamos, contudo, é de modificar o conteúdo do corpo baseando em algumas ocasiões, mas sem alterar a classe principal de email.

Decorator principal

Esta é a nossa classe principal decorator, o qual armazena a referência para a nossa classe principal email e modifica o comportamento como necessário. Aqui nós modificamos o nosso método abstrato, loadBody, o qual o sub decorator precisa de implementar para mudar de comportamento.

Sub Decorator

Aqui nós criamos duas subclasses do decorator principal, o qual atualmente faz com que haja alteração de comportamento para a classe principal de email.

Juntando tudo

Nós criamos todos os elementos necessários. Tudo que necessitamos é usar o nosso código e aproveitar.

Agora iremos usar a classe decorator de várias formas, conforme necessário:

Agora podemos ver que alteramos o corpo do email sem modificar a classe principal do email.

Conclusão

Toda a aplicação tem necessidades de algum tipo de alteração e/ou melhoramento em intervalos uniformes. Assim, em tal caso nós podemos implementar o padrão de design decorator e irá melhorar a qualidade do código e fazer o nosso código mais extensível.

Este foi o meu esforço para explicar-vos o padrão decorator, mas se tendes quaisquer comentários ou questões, por favor não hesitem e adiciona-os no feed abaixo.

Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.