X

Traits em PHP: herança horizontal

Traits são mecanismos que ajudam na reutilização de código, resolvendo o problema da falta de herança múltipla. Explicaremos de forma simples o que são Traits.

A equipe da Turbosite compartilha com essa postagem um artigo retirado do blog . A postagem abaixo explica, de forma bem simples, o que são Traits em PHP.

O PHP não suporta herança múltipla e por este motivo, às vezes ficamos limitados em algumas decisões de projeto. O maior problema neste ponto é que toda herança até agora (PHP 5.3.x) é vertical, ou seja, se precisar de um nível de abstração diferente no meio do processo, ou precisarei adicionar a nova abstração e reescrever tudo abaixo dela, ou ainda, terei que duplicar o código pois não conseguirei satisfazer a herança. É nesse ponto que os Traits aparecem. Diferentemente da herança (vertical), os Traits possibilitam-nos criar heranças horizontais (blog Hélio Costa).

Traits são mecanismos que ajudam (e muito) a reutilização de código, e servem perfeitamente para resolver o problema da falta de herança múltipla. Suponhamos que você tenha duas ou mais classes que precisam usar um método/comportamento em comum, antes da versão 5.4 você faria algo do tipo:

 

Primeiro temos nossa classe Log, que serviria pra salvar mensagens de log (imagine uma classe completa, que faça algo de útil):

<?php
class Log {
 
     public function log($message) {
          // Salva $message em um log de alguma forma
      }
 
}

 

E agora você tem outras classes que fazem uso dessa funcionalidade (salvar logs), mas essas classes não podem (e nem deveriam) estender Log, então você faria algo do tipo:

class Usuario extends Model {
 
     protected $Log;
 
     public function __construct() {
          $this->Log = new Log();
     }
 
     public function save() {
          // Salva o usuário de alguma forma
          // ...
 
          // Salva uma mensagem de log
          $this->Log->log('Usuário criado');
     }
 
}
 
class Carrinho extends Produto {
 
     protected $Log;
 
     public function __construct() {
          $this->Log = new Log();
     }
 
     public function clear() {
          // Limpa o carrinho de alguma forma
          // ...
 
          // Salva uma mensagem de log
          $this->Log->log('Carrinho de compras limpo');
     }
 
}

Mais uma vez, o conteúdo ou métodos dessas classes não importa.. o que importa aqui é o trabalho que temos para poder usar o Log::log() para salvar mensagens de log.

 

Já na versão 5.4, podemos transformar a classe Log numa Trait:

trait Log {
 
     public function log($message) {
          // Salva $message em um log de alguma forma
     }
 
}

E manter o comportamento das nossas classes, de forma bem mais simples:

class Usuario extends Model {
 
     use Log;
 
     public function save() {
          // Salva o usuário de alguma forma
          // ...
 
          // Salva uma mensagem de log
          $this->log('Usuário criado');
     }
 
}
class Carrinho extends Produto {
 
     use Log;
 
     public function clear() {
          // Limpa o carrinho de alguma forma
          // ...
 
          // Salva uma mensagem de log
          $this->log('Carrinho de compras limpo');
     }
 
}

Podemos usar o método log() diretamente (sem a necessidade de instanciar um objeto de Log) pois nossas classes adquiriram as características (métodos e atributos) de Log!

 

Conclusão

Traits são de fato recursos bem interessantes e muitos frameworks estão se adaptando à esse poderoso recurso.


This post was last modified on 4 de maio de 2018 13:16

Turbosite:

This website uses cookies.