¿Cuándo usar un trait en PHP? Ventajas, límites y alternativas

¿Te preguntas «cuándo hay que crear un trait» y qué ventajas e inconvenientes tiene? O puede que simplemente no sepas qué es un trait en PHP, y en ese caso te invito a leer el artículo que escribí sobre el tema. En mi caso,

¿Cuándo usar un trait en PHP? Ventajas, límites y alternativas

¿Te preguntas « cuándo hay que crear un trait » y qué ventajas e inconvenientes tiene? O puede que simplemente no sepas qué es un trait en PHP, y en ese caso te invito a leer el artículo que escribí sobre el tema.

En mi caso, las pocas veces que he creado un trait ha sido para widgets de Elementor o de Prestashop. Por ejemplo, un widget de Elementor ya hereda de una clase, no me apetece nada encadenar una clase que hereda de otra, y esa de otra, hasta llegar a mi widget solo para compartir dos o tres métodos. Ahí es donde entra el trait, que me permite justamente poner esos métodos en común. En el fondo, y para simplificar, un trait equivale a un copiar y pegar.

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

protected function registerCarouselSection(array $args = [])
    {
       // Resto del código para mostrar opciones
       // de configuración en Elementor
    }
}

Las ventajas de un trait en PHP

  • Si quieres reutilizar código entre varias clases, el trait es una alternativa a extender la clase. En ese caso suele ser la mejor opción, porque no forma parte de la jerarquía de tipos: una clase que usa un trait no es «una instancia de ese trait».

  • Un trait te ahorra el copiar y pegar manual, porque hace ese copiar y pegar en tiempo de compilación.

Los inconvenientes de un trait en PHP

Por otro lado, los traits plantean varios problemas. Por ejemplo:

  • Cuando un trait añade uno o varios métodos públicos a una clase, a menudo querrías declarar esos métodos en una interfaz que la clase implementara automáticamente al usar el trait. No se puede: un trait no puede implementar una interfaz. Si quieres ese resultado, tienes que usar el trait e implementar la interfaz de forma explícita.

  • Los traits no tienen métodos ni propiedades «privados» que sean suyos. A menudo me gustaría ocultar ciertas cosas a la clase que usa el trait, pero no hay forma de hacerlas «privadas». Todo lo que declares como privado en el trait seguirá siendo accesible desde la clase que lo usa. Dicho de otro modo, un trait no puede encapsular nada.

Qué alternativas hay a los traits en PHP

En la práctica siempre acabas encontrando una alternativa al trait. Aquí van algunas:

  • Si el trait tiene responsabilidades de servicio, es mejor convertirlo en un servicio de verdad, que puede y debe inyectarse como argumento del constructor en el servicio que lo necesita. Eso es composición de comportamiento (composing behavior) en lugar de herencia de comportamiento. Este enfoque también sirve cuando quieres deshacerte de las clases padre.

  • Si el trait añade a una entidad un comportamiento que es el mismo en otra entidad, suele ser buena idea introducir un value object en PHP y usarlo en su lugar.

Conclusión

Para mí los traits son una solución cómoda: más una forma de organizar el código que otra cosa, en lugar de duplicar líneas o de encadenar herencias unas dentro de otras.

PHP

Damien Flandrin Desarrollador web desde 2010, creador de Gekkode y de Email Impact. Cada artículo se prueba en un proyecto real antes de publicarse. Contacto
Newsletter

Las nuevas pruebas, tutoriales y proyectos, por correo.

Pruebas reproducibles, código versionado, resultados fechados. Nunca spam.