Quando usar um trait em PHP: vantagens, limites e alternativas

Quando usar um trait em PHP: vantagens, limites e alternativas

Andas a perguntar-te «quando é que se deve criar um trait?» e quais são as vantagens e os inconvenientes? Ou talvez não saibas simplesmente o que é um trait em PHP e, nesse caso, convido-te a ler o artigo que escrevi sobre o assunto.

Da minha parte, as raras vezes em que criei um trait foi para construir widgets Elementor ou Prestashop. Pega num widget Elementor: já estende uma classe, e não me apetece escrever uma classe que estende outra, que estende outra, até chegar ao meu widget, só para partilhar dois ou três métodos. É aí que o trait entra e me deixa partilhar exatamente esses métodos. Em resumo, e para simplificar, um trait acaba por ser um copiar-colar.

php
trait CarouselTrait
{
    public function getScriptDepends()
    {
        return ['swiper'];
    }

protected function registerCarouselSection(array $args = [])
    {
       // Restante código para mostrar as opções
       // de configuração no Elementor
    }
}

As vantagens de um trait em PHP

  • Se queres reutilizar código entre várias classes, o trait é uma alternativa a estender a classe. Nesse caso, o trait pode ser a melhor opção porque não faz parte da hierarquia de tipos: uma classe que usa um trait não é «uma instância desse trait».

  • Um trait poupa-te um copiar-colar manual ao oferecer-te um copiar-colar em tempo de compilação.

Os inconvenientes de um trait em PHP

Por outro lado, os traits levantam vários problemas. Por exemplo:

  • Quando um trait acrescenta um ou mais métodos públicos a uma classe, é frequente querer declarar esses métodos numa interface que a classe implementaria automaticamente ao usar o trait. É impossível. Um trait não pode implementar uma interface. Tens de usar o trait e implementar a interface explicitamente se quiseres esse resultado.

  • Os traits não têm métodos nem propriedades «privados» que lhes pertençam. Gosto muitas vezes de esconder certas coisas da classe onde o trait é usado, mas não há forma de as tornar «privadas». Tudo o que for definido como privado no trait continua acessível à classe que o usa. Um trait é, portanto, incapaz de encapsular seja o que for.

Que alternativas existem aos traits em PHP

Seja como for, na prática há sempre alternativas ao trait. A título de exemplo, aqui ficam algumas:

  • Se o trait tem responsabilidades de serviço, mais vale transformá-lo num serviço a sério, que pode e deve ser injetado como argumento de construtor no serviço que dele precisa. É o que se chama comportamento composto (ou composing behavior) em vez de comportamento herdado. Esta abordagem serve também quando queres livrar-te das classes-mãe.

  • Se o trait acrescenta a uma entidade um comportamento que é o mesmo noutra entidade, muitas vezes vale a pena introduzir um value object em PHP e usá-lo no lugar dele.

Conclusão

Para mim, os traits são uma solução de facilidade: são mais uma forma de organizar o código do que outra coisa, em vez de duplicar linhas ou de encaixar heranças umas dentro das outras.

PHP

Damien Flandrin Programador web desde 2010, criador da Gekkode e do Email Impact. Cada artigo é testado num projeto real antes de ser publicado. Contacto
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.