PHP Patterns parte 6: Decorator

Posted on novembro 10, 2010. Filed under: PHP |

Uma classe que implementa o pattern “Decorator” permite adicionar funcionalidades em outra classe existente sem que haja necessidade de alterá-la, através de métodos intermediários. Decorator é uma forma flexível alternativa a utilização de “herança” de classe. Em determinadas situações o decorator ajuda a evitar uma explosão de “sub-classes” deixando o código mais simples e fácil de se manter. Geralmente a classe “Decorator” recebe uma referência de um objeto e cria métodos que servirão para “decorar” este objeto. Um exemplo do pattern decorator pode ser encontrado no Zend Framework, mais especificamente na classe Zend_Form. O Pattern Decorator serve como uma luva ao se trabalhar na criação de elementos de formulários HTML.

Para exemplificar a utilização do pattern Decorator vamos criar uma classe chamada “Texto” que possui um método que retorna uma string que foi passada como parâmetro no construtor.

<?php
class Texto {
  protected $texto;

  public function __construct($texto)
  {
    $this->texto = $texto;
  }

  public function obtemTexto()
  {
    return $this->texto;
  }
}

Em seguida vamos criar nossas classes “Decorator”. A classe decorator, chamada “TextoAspasDecorator”, irá receber o objeto da classe “Texto” no construtor. Portanto, no decorator, temos disponível o método “exibeTexto()” que irá retornar a string armazenada no objeto “Texto” formatada com aspas duplas no início e no fim. Detalhe que podemos observar aqui é que estamos deixando o objeto original intacto.

<?php
class TextoAspasDecorator {
  protected $obj_texto;

  public function __construct(Texto $obj_texto)
  {
    $this->obj_texto = $obj_texto;
  }

  public function exibeTexto()
  {
    return '"' . $this->obj_texto->obtemTexto() . '"';
  }
}

Criei mais um exemplo de decorator abaixo. O nome da classe é “TextoExclamacaoDecorator”. Ela possui a mesma estrutura do exemplo anterior, a única diferença é que a formatação da string ao invés de usar aspas duplas esta usando exclamação “!”

<?php
class TextoExclamacaoDecorator {
  protected $obj_texto;

  public function __construct(Texto $obj_texto)
  {
    $this->obj_texto = $obj_texto;
  }

  public function exibeTexto()
  {
    return '!' . $this->obj_texto->obtemTexto() . '!';
  }
}

Vamos para à utilização das classes criadas acima. Veja como é simples a utilização de nossos decorators:

// instância da classe Texto
$texto = new Texto("Mensagem Exemplo");

// Instânciando as classes Decorators e
// passando o objeto $texto para o construtor
$decorator_aspas = new TextoAspasDecorator($texto);
$decorator_exclamacao = new TextoExclamacaoDecorator($texto);

// printando o texto original
echo $texto->obtemTexto() . PHP_EOL;

// Printando os textos formatados pelos decorators
echo $decorator_aspas->exibeTexto() . PHP_EOL;
echo $decorator_exclamacao->exibeTexto();

Resultado:
Mensagem Exemplo
"Mensagem Exemplo"
!Mensagem Exemplo!

O Zend Framework faz a utilização deste pattern na renderização dos elementos de formulário usando Zend_Form. É claro que a implementação no Zend Framework é diferente da nossa, eu usei exemplos bem simples para facilitar o entendimento, porém existem diversas outras maneiras de implementar este pattern.
Nos forms do Zend Framework é possível definir com quais tags os elementos e labels de formulários serão envolvidos. Você também pode definir se serão exibidos mensagens de erro e de descrição na renderização do formulário, entre outras. Para maiores detalhes acesse: ZF Elementos de Formulário.

Make a Comment

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

Liked it here?
Why not try sites on the blogroll...

%d blogueiros gostam disto: