Wanneer gebruik je een trait in PHP? Voordelen en alternatieven

Wanneer gebruik je een trait in PHP? Voordelen en alternatieven

Vraag je je af wanneer je een trait aanmaakt, en wat de voordelen en de nadelen ervan zijn? Of weet je simpelweg nog niet wat een trait in PHP is, dan raad ik je aan eerst het artikel te lezen dat ik daarover heb geschreven.

Zelf heb ik maar zelden een trait geschreven, en dan ging het om widgets voor Elementor of PrestaShop. Een Elementor-widget erft al van een klasse. Ik heb weinig zin om daar nog een klasse tussen te schuiven, en daarboven nog een, alleen om twee of drie methoden te delen. Precies daar komt de trait van pas: die deelt die methoden wel. In de kern komt een trait neer op een kopieer-en-plakactie, als je het even simpel wilt houden.

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

protected function registerCarouselSection(array $args = [])
    {
       // Rest van de code die de configuratieopties
       // in Elementor toont
    }
}

De voordelen van een trait in PHP

  • Wil je code hergebruiken tussen meerdere klassen, dan is een trait een alternatief voor overerving. Vaak is de trait dan de betere keuze, want hij maakt geen deel uit van de typehiërarchie: een klasse die een trait gebruikt, is geen “instantie van die trait”.

  • Een trait bespaart je handmatig kopiëren en plakken, en doet dat werk op het moment van compileren.

De nadelen van een trait in PHP

Daar staat tegenover dat traits verschillende problemen opleveren. Bijvoorbeeld:

  • Voegt een trait een of meer publieke methoden aan een klasse toe, dan wil je die methoden meestal in een interface vastleggen die de klasse automatisch implementeert zodra ze de trait gebruikt. Dat kan niet. Een trait kan geen interface implementeren. Je gebruikt dus de trait én implementeert de interface expliciet als je dat wilt bereiken.

  • Traits hebben geen eigen “private” methoden en eigenschappen. Ik verberg graag een en ander voor de klasse die de trait gebruikt, maar echt privé maken lukt niet. Alles wat je in de trait als private declareert, blijft bereikbaar vanuit de klasse die hem gebruikt. Een trait kan dus niets inkapselen.

Welke alternatieven zijn er voor traits in PHP?

In de praktijk is er altijd wel een alternatief voor een trait. Een paar voorbeelden:

  • Draagt de trait de verantwoordelijkheden van een service, maak er dan een echte service van. Die kun je, en die hoor je, als constructorargument te injecteren in de service die hem nodig heeft. Dat heet composable behavior, gedrag samenstellen in plaats van gedrag erven. Dezelfde aanpak helpt je ook af van je basisklassen.

  • Voegt de trait gedrag toe aan een entiteit, en is dat gedrag hetzelfde voor een andere entiteit, dan is het vaak verstandiger om een value object in PHP te introduceren en dat te gebruiken.

Conclusie

Traits zijn wat mij betreft de gemakkelijke oplossing: eerder een manier om je code te ordenen dan iets anders, zodat je geen regels hoeft te dupliceren en geen overervingen in elkaar hoeft te schuiven.

PHP

Damien Flandrin Webdeveloper sinds 2010, maker van Gekkode en Email Impact. Elk artikel wordt vóór publicatie getest op een echt project. Contact
Nieuwsbrief

Nieuwe tests, tutorials en projecten, per e-mail.

Reproduceerbare tests, geversioneerde code, gedateerde resultaten. Nooit spam.