Accueil / Tutoriels / Decorator
Decorator
Publié le 3 Mars 2025Decorator (Décorateur en français) est un pattern structurel qui permet de modifier le comportement initial d’un objet, mais sans en modifier sa structure. Ce pattern favorise l’utilisation de la composition plutôt que l’héritage d’une classe parente.
Le principe
Exemples d’utilisations
Mise en forme d’un texte
Mise en cache du résultat d’une requête SQL
Points d’attentions
Implémenter un décorateur
Exemple d'utilisation d'un Decorator avec Go
package data
type DataSource interface {
WriteData(data string)
ReadData() string
}
package data
type FileDataSource struct {
data string
}
func (f *FileDataSource) WriteData(data string) {
f.data = data
}
func (f *FileDataSource) ReadData() string {
return f.data
}
package decorators
import (
"fmt"
"practice/designpatterns/decorator-decorticode/data"
)
type EncryptionDecorator struct {
Source data.DataSource
}
func (e *EncryptionDecorator) WriteData(data string) {
encryptedData := reverse(data)
fmt.Println("Données chiffrés : ", encryptedData)
e.Source.WriteData(encryptedData)
}
func (e *EncryptionDecorator) ReadData() string {
encryptedData := e.Source.ReadData()
decryptedData := reverse(encryptedData) // On "déchiffre" en inversant à nouveau
fmt.Println("Données déchiffrés : ", decryptedData)
return decryptedData
}
func reverse(s string) string {
runes := []rune(s)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}
package decorators
import (
"log"
"practice/designpatterns/decorator-decorticode/data"
)
type LoggingDecorator struct {
Source data.DataSource
}
func (l *LoggingDecorator) WriteData(data string) {
log.Printf("Écriture dans un fichier de logs : %s", data)
l.Source.WriteData(data)
}
func (l *LoggingDecorator) ReadData() string {
readData := l.Source.ReadData()
log.Printf("Lecture du fichier de logs : %s", readData)
return readData
}
package main
import (
"fmt"
"practice/designpatterns/decorator-decorticode/data"
"practice/designpatterns/decorator-decorticode/decorators"
)
func main() {
file := &data.FileDataSource{}
// Mise en place du décorateur de chiffrement sur la source de données.
encryptedDataSource := &decorators.EncryptionDecorator{Source: file}
// Mise en place du décorateur de logging sur le décorateur de chiffrement.
decoratedDataSource := &decorators.LoggingDecorator{Source: encryptedDataSource}
// Écriture des données
decoratedDataSource.WriteData("Je veux chiffrer cette phrase")
// Lecture des données
result := decoratedDataSource.ReadData()
fmt.Println("Fin du traitement : ", result)
}
Le même exemple en PHP
namespace Practice\DesignPatterns\Decorator;
interface DataSourceInterface
{
public function writeData(string $data): void;
public function readData(): string;
}
namespace Practice\DesignPatterns\Decorator;
class FileDataSource implements DataSourceInterface {
private string $data = "";
public function writeData(string $data): void {
$this->data = $data;
}
public function readData(): string {
return $this->data;
}
}
namespace Practice\DesignPatterns\Decorator;
class EncryptionDecorator implements DataSourceInterface {
private DataSourceInterface $source;
public function __construct(DataSourceInterface $dataSource) {
$this->source = $dataSource;
}
public function writeData(string $data): void {
$encryptedData = $this->reverse($data);
echo "Données chiffrés : " . $encryptedData;
$this->source->writeData($encryptedData);
}
public function readData(): string {
$encryptedData = $this->source->readData();
echo "Données déchiffrés : " . $encryptedData;
return $this->reverse($encryptedData);
}
private function reverse(string $text): string {
return strrev($text);
}
}
namespace Practice\DesignPatterns\Decorator;
class LoggingDecorator implements DataSourceInterface {
private DataSourceInterface $source;
public function __construct(DataSourceInterface $dataSource) {
$this->source = $dataSource;
}
public function writeData(string $data): void {
echo "Écriture dans un fichier de logs : " . $data;
$this->source->writeData($data);
}
public function readData(): string {
$data = $this->source->readData();
echo "Lecture du fichier de logs : " . $data;
return $data;
}
}
declare(strict_types=1);
use Practice\DesignPatterns\EncryptionDecorator;
use Practice\DesignPatterns\FileDataSource;
use Practice\DesignPatterns\LoggingDecorator;
require "./vendor/autoload.php";
// Utilisation :
// 1. Création de la source de données de base.
$fileDataSource = new FileDataSource();
// 2. Application du décorateur d'encryption.
$encryptedDataSource = new EncryptionDecorator($fileDataSource);
// 3. Application du décorateur de logging sur le décorateur d'encryption.
$decoratedDataSource = new LoggingDecorator($encryptedDataSource);
// Écriture des données via la chaîne de décorateurs.
$decoratedDataSource->writeData("Je veux chiffrer cette phrase");
// Lecture des données via la chaîne de décorateurs.
$result = $decoratedDataSource->readData();
echo "Fin du traitement : " . $result . "\n";