Dans l'écosystème Drupal, la majorité des fonctionnalités principales et des modules contrib sont construits autour de services. Pour adapter ces composants à des besoins spécifiques, deux approches s'offrent aux développeurs : la décoration de service et le remplacement complet. Le choix entre ces méthodes dépend de l'objectif et de l'impact désiré sur le système existant.
Comprendre la Décoration de Service
Inspirée du Design Pattern Decorator, cette technique permet d'étendre dynamiquement un service existant sans modifier son code source. Idéale pour des ajustements ciblés, elle préserve l'intégrité du composant original tout en permettant des personnalisations contextuelles.
Analogie Pratique 🎨
Imaginez un tableau (service original) que vous souhaitez protéger tout en l'exposant :
- ✅ Décoration : Ajouter un cadre et une vitre sans toucher à la peinture
- ❌ Remplacement : Repeindre entièrement le tableau original
Cas d'Usage Typique
Prenons l'exemple d'un service json_exporter
qui génère des descriptions de contenu :
Service original (core/modules/json_api/src/JsonExporter.php)
services:
json_exporter:
class: Drupal\json_api\JsonExporter
arguments: ['@config.factory']
// modules/custom/json_api/src/JsonExporter.php
namespace Drupal\json_api;
class JsonExporter {
public function getDescription($entity) {
return $entity->get('body')->value;
}
public function export($entity) {
return [
'id' => $entity->id(),
'description' => $this->getDescription($entity)
];
}
}
Tache à faire :
Ajouter systématiquement un copyright légal à la fin de chaque description générée.
Étape 1 - Déclaration du Décorateur
my_module.services.yml
services:
my_module.json_exporter_decorator:
class: Drupal\my_module\JsonExporterDecorator
arguments: ['@json_exporter.inner']
decorates: json_exporter
public: false
Étape 2 - Implémentation PHP
// modules/custom/my_module/src/JsonExporterDecorator.php
namespace Drupal\my_module;
use Drupal\json_api\JsonExporter;
class JsonExporterDecorator extends JsonExporter {
protected $originalService;
public function __construct(JsonExporter $original_service) {
$this->originalService = $original_service;
}
public function getDescription($entity) {
$description = $this->originalService->getDescription($entity);
return $description . "\n\nCopyright © " . date('Y');
}
}
Décoration du service La décoration de service tire son origine du concept "Decorator pattern". Le motif décorateur est un modèle de conception qui permet d'ajouter un comportement à un individu objet, dynamiquement, sans affecter le comportement des autres instances de la même classe. Cela permet de garder globalement le même comportement. Exemple logique : Nous avons un service qui permet d'exposer les données en JSON et qui fournit contient une methode getDesription. Nous souhaitons supprimer par ajouter un texte à la fin de la description. Pour effectuer cette action, nous allons ajouter une décoration sur ce service. Exemple de code :