OOP Mastery (POO)
Thème :
Junior
1 vues ·9/17 leçonsBonnes Pratiques des Traits
Les Traits peuvent être puissants pour la réutilisation de code, mais ils peuvent aussi mener à des cauchemars de maintenance s’ils sont mal utilisés. Suivez ces bonnes pratiques.
Bons Cas d’Usage
1. Les Préoccupations Transversales (Cross-Cutting Concerns)
<?php
// Préoccupation de logging partagée entre classes non liées
trait Loggable
{
protected function log(string $message, string $level = 'info'): void
{
$context = [
'class' => static::class,
'timestamp' => date('c'),
];
error_log("[$level] $message " . json_encode($context));
}
protected function logError(Throwable $e): void
{
$this->log($e->getMessage(), 'error');
}
}
class UserService
{
use Loggable;
public function createUser(array $data): User
{
$this->log('Création utilisateur : ' . $data['email']);
// ...
}
}
class PaymentService
{
use Loggable;
public function processPayment(float $amount): void
{
$this->log("Traitement du paiement : $amount €");
// ...
}
}
2. Les Méthodes Utilitaires Sans État
<?php
trait StringHelpers
{
protected function slugify(string $text): string
{
return strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $text), '-'));
}
protected function truncate(string $text, int $length, string $suffix = '...'): string
{
if (strlen($text) <= $length) {
return $text;
}
return substr($text, 0, $length - strlen($suffix)) . $suffix;
}
}
Les Anti-Patterns à Éviter
1. Les Traits Comme Substitut à l’Héritage
<?php
// MAUVAIS : Utiliser un trait pour partager un état qui devrait être hérité
trait BaseEntity
{
protected int $id;
protected DateTimeImmutable $createdAt;
protected DateTimeImmutable $updatedAt;
// Ce devrait probablement être une classe abstraite !
}
// MIEUX : Utiliser une classe abstraite pour l'état partagé
abstract class Entity
{
protected int $id;
protected DateTimeImmutable $createdAt;
protected DateTimeImmutable $updatedAt;
}
2. Les Traits avec des Dépendances Cachées
<?php
// MAUVAIS : Le trait assume que des propriétés existent
trait Publishable
{
public function publish(): void
{
$this->status = 'published'; // D'où vient $status ?
$this->publishedAt = new DateTime(); // Magie noire !
}
}
// MIEUX : Rendre les dépendances explicites
trait Publishable
{
abstract protected function getStatus(): string;
abstract protected function setStatus(string $status): void;
abstract protected function setPublishedAt(DateTimeInterface $date): void;
public function publish(): void
{
$this->setStatus('published');
$this->setPublishedAt(new DateTimeImmutable());
}
}
3. L’Explosion de Traits
<?php
// MAUVAIS : Trop de traits rendent le code difficile à suivre
class User
{
use Timestamps;
use SoftDeletes;
use HasUuid;
use Searchable;
use Cacheable;
use Loggable;
use Validatable;
use Serializable;
// D'où vient n'importe quelle méthode ?!
}
// MIEUX : Limiter les traits, préférer la composition
class User
{
use Timestamps; // Juste les timestamps
public function __construct(
private CacheInterface $cache,
private LoggerInterface $logger
) {}
}
Tester les Traits
<?php
// Créer une classe anonyme pour tester le trait
class TimestampableTest extends TestCase
{
public function testSetsCreatedAt(): void
{
$instance = new class {
use Timestampable;
};
$instance->setCreatedAt();
$this->assertInstanceOf(
DateTimeImmutable::class,
$instance->getCreatedAt()
);
}
}
Les Grimoires
📘 Cette leçon fait partie du cours Maîtrise de la POO en PHP sur la plateforme d’apprentissage RostoDev.
Prêt à passer à la suite ?
Vous avez terminé cette leçon sur Bonnes Pratiques des Traits. Continuez votre apprentissage avec la prochaine leçon ou explorez d'autres formations.