I Traits nascono  nella versione del PHP 5.4 e sono stati introdotti per l’esigenza di superare alcuni problemi dovuti all’ereditarietà.

Infatti uno dei problemi di PHP come linguaggio di programmazione è il fatto che è possibile avere un’unica ereditarietà. Ossia una classe può ereditare solo da un’altra classe.

Tuttavia, molto spesso sarebbe utile ereditare da altre classi. Ad esempio, potrebbe essere desiderabile ereditare metodi da un paio di classi diverse al fine di prevenire la duplicazione del codice.

 

Per tutti questi motivi in PHP 5.4 è stata aggiunta una nuova funzionalità della lingua nota come Traits in italiano ovviamente tratto . Un Tratto è un po ‘come un Mixin in quanto ti permette di mescolare classi Trait in una classe esistente. Ciò significa che puoi ridurre la duplicazione del codice e ottenere i benefici evitando i problemi dell’ereditarietà multipla.

Quali sono i traits in  PHP?

Un Trait è semplicemente un gruppo di metodi che si desidera includere in un’altra classe. Un trait, come una classe astratta , non può essere istanziato da solo.

Un esempio di un tratto potrebbe essere:

trait Condividi {
 
 public function cond($item)
 {
 return 'condividi questo oggetto';
 }
 
}

Potresti quindi includere questo Trait all’interno di altre classi come questa:

class Articolo {
 
 use Condividi;
 
}
 
class Commenta {
 
 use Condividi;
 
}

Ora se dovessi creare nuovi oggetti da queste classi, scopriresti che entrambi hanno il metodo cond disponibile

$post = new Articolo;
echo $post->cond(''); // Condividi questo articolo
 
$comment = new Commenta;
echo $comment->cond(''); // 'Condividi questo articolo


Come funzionano i Traits?

Come puoi vedere dall’esempio sopra, sia Articolo che  Commenta hanno metodo cond() disponibile, pur non avendo definito quel metodo.

Quindi possiamo definire un Traits come un modo per copiare e incollare il codice durante l’esecuzione.

Ciò significa che il Trait  è copiato nelle classi Articolo e Commenta così quando istanziate  il metodo  cond() e quindi il codice al suo interno sarà disponibile.

In che modo i Traits sono diversi dalle classi astratte?

Fondamentalmente le classi astratte non si basano sull’eredità.

Immagina se le classi  Articolo a Commenta dovessero ereditare da una classe astratta . Probabilmente vorremmo fare qualcosa di più della semplice condivisione di post e commenti sui siti di social media, quindi probabilmente ci ritroveremo con un complesso albero ereditario come questo:

class AbstractValidate extends AbstractCache {}
class AbstractSocial extends AbstractValidate {}
class Post extends AbstractSocial {}

Questa complicata ereditarietà è piuttosto sgradevole e di non immediata comprensione, ma aggiunge anche complicazioni quando un oggetto più semplice non ha una struttura di ereditarietà simile. Ad esempio, se avessimo un oggetto che non dovesse consentire la condivisione social, questo oggetto richiederebbe una struttura ereditaria leggermente diversa.

In che modo i Traits sono diversi dalle interfacce?

Come Funzionano i Traits in PHP

I Traits somigliano molto alle interfacce. Sia i Traits che  le interfacce sono in genere semplici, concisi e poco utili senza una classe effettiva implementata. Tuttavia la differenza tra i due è importante.

Un’interfaccia  dice “questo oggetto è in grado di fare questa cosa”, mentre un Trait sta dando all’oggetto la capacità di fare la cosa. Vediamo un esempio per comprendere meglio il concetto



// Interface
interface Sociable {
 
 public function like();
 public function share();
 
}
 
// Trait
trait Sharable {
 
 public function share($item)
 {
 // condivi questo oggetto
 } 
 
}
 
// Class
class Post implements Sociable {
 
 use Sharable;
 
 public function like()
 {
 //
 }
 
}

In questo esempio abbiamo Sociable un’interfaccia che afferma che la classe Post  è in grado di usufruire  di like()e share().

Il Sharable Trait implementa il metodo share() e  like() che è implementato nella classe Post

Quindi, come puoi vedere, potremmo utilizzare  Post dell’oggetto per vedere se implementa l’interfaccia Sociable, mentre il Trait definisce un metodo riutilizzabile che possiamo poi mescolare ad altre classi simili. Vediamo

$post = new Post;
 
if($post instanceOf Sociable)
{
 $post->share('hello world');
}

Quali sono i vantaggi dei Traits?

Il vantaggio dell’utilizzo dei Traits è che si riduce la duplicazione del codice, evitando al contempo complicate eredità di classe che potrebbero non avere senso nel contesto dell’applicazione.

Ciò consente di definire Traits semplici chiari e concisi e quindi di integrare tali funzionalità laddove veramente servono.

Quali sono gli svantaggi dei Traits?

Tuttavia con ciò detto, ci sono possibili inconvenienti quando si utilizzano i Traits.

I Traits rendono molto facile scrivere classi ampie che hanno molte responsabilità. Un Trait è essenzialmente un modo per “copiare e incollare” il codice tra le classi. Avendo un modo per aggiungere semplicemente un altro gruppo di metodi a una classe.

Altri svantaggi nell’usare i Traits è che non sono in grado di vedere tutti i metodi di una classe quando si guarda il codice sorgente, come pure i conflitti di metodo o la duplicazione della logica.

Penso che  se usati correttamente, siano uno strumento fantastico da avere a nostra disposizione. Tuttavia, i Traits possono anche essere la stampella per la programmazione pigra. È molto semplice aggiungere un Trait per risolvere il tuo problema immediato. Spesso la composizione è l’approccio migliore sull’ereditarietà o l’utilizzo di un tratto.