Décorateur (patron de conception)

Un article de Wikipédia, l'encyclopédie libre.
Aller à : navigation, rechercher
Page d'aide sur l'homonymie Pour les articles homonymes, voir Décorateur.

En génie logiciel, un décorateur est le nom d'une des structures de patron de conception.

Un décorateur permet d'attacher dynamiquement de nouvelles responsabilités à un objet. Les décorateurs offrent une alternative assez souple à l'héritage pour composer de nouvelles fonctionnalités.

Exemple en C#[modifier | modifier le code]

Ici l'héritage est utilisé.

//______________________________________________________________________
// Déclarations
 
abstract class Voiture {
    public abstract double Prix { get; }
}
class  AstonMartin : Voiture {
    public override double Prix { get { return 999.99; } }
}
 
//______________________________________________________________________
// Décorateurs
 
class Option : Voiture {
    protected Voiture _originale;
    protected double _tarifOption;
    public Option(Voiture originale, double tarif) { 
        _originale = originale;
        _tarifOption = tarif; 
    }
    public override double Prix {
        get { return _originale.Prix + _tarifOption; }
    }
}
 
class VoitureAvecClimatisation : Option {
    public VoitureAvecClimatisation (Voiture originale) : base(originale, 1.0) { }
}
class VoitureAvecParachute : Option {
    public VoitureAvecParachute (Voiture originale) : base(originale, 10.0) { }
}
class VoitureAmphibie : Option {
    public VoitureAmphibie (Voiture originale) : base(originale, 100.0) { }
}
 
//______________________________________________________________________
// Implémentation
 
class Program {
    static void Main() {
        Voiture astonMartin= new AstonMartin();
        astonMartin = new VoitureAvecClimatisation(astonMartin);
        astonMartin = new VoitureAvecParachute(astonMartin);
        astonMartin = new VoitureAmphibie(astonMartin);
 
        Console.WriteLine(astonMartin.Prix); // affiche 1110.99
    }
}

Exemple en C++[modifier | modifier le code]

# include <iostream>
# include <memory>
 
class IVoiture
{
public:
  virtual double prix() = 0;
};
 
class Aston_martin : public IVoiture
{
public:
  virtual double prix() override { return 999.99l; }
};
 
class Option_voiture : public IVoiture
{
public:
  Option_voiture(std::unique_ptr<IVoiture> voiture, double prix_option)
    : voiture_(std::move(voiture))
    , prix_option_(prix_option)
  {}
  virtual double prix() override { return voiture_->prix() + prix_option_; }
protected:
  std::unique_ptr<IVoiture> voiture_;
  double prix_option_;
};
 
class Option_clim : public Option_voiture
{
public:
  Option_clim(std::unique_ptr<IVoiture> voiture) : Option_voiture(std::move(voiture), 1.0) {}
};
 
class Option_parachute : public Option_voiture
{
public:
  Option_parachute(std::unique_ptr<IVoiture> voiture) : Option_voiture(std::move(voiture), 10.0) {}
};
 
class Option_amphibie : public Option_voiture
{
public:
  Option_amphibie(std::unique_ptr<IVoiture> voiture) : Option_voiture(std::move(voiture), 100.0) {}
};
 
int main()
{
  auto voiture = std::unique_ptr<IVoiture>(std::make_unique<Aston_martin>());
  voiture = std::make_unique<Option_clim>(std::move(voiture));
  voiture = std::make_unique<Option_parachute>(std::move(voiture));
  voiture = std::make_unique<Option_amphibie>(std::move(voiture));
  std::cout << voiture->prix() << "\n"; // affiche 1110.99
  return 0;
}

Exemple en PHP[modifier | modifier le code]

<?php
 
// Interface pour rendre un objet affichable
interface Affichable {
	public function affiche();
}
 
// Classe contenant un message affichable
class Message implements Affichable {
 
	protected $message = '';
 
	public function __construct($message) {
		$this->message = $message;
	}
 
	public function affiche() {
		echo $this->message;
	}
 
}
 
// Une classe abstraite de décoration de message affichable
abstract class DecorateurDeMessage implements Affichable {
 
	protected $messageDecore = null;
 
	public function __construct(Affichable $messageDecore) {
		$this->messageDecore = $messageDecore;
	}
}
 
// Une classe pour "décorer" un message en gras
class MessageEnGras extends DecorateurDeMessage {
 
	public function affiche() {
		echo '<strong>';
		$this->messageDecore->affiche();
		echo '</strong>';
	}
}
 
// Une classe pour "décorer" un message en italique
class MessageEnItalique extends DecorateurDeMessage {
 
	public function affiche() {
		echo '<em>';
		$this->messageDecore->affiche();
		echo '</em>';
	}
}
 
// Création du message
$message = new Message('le message');
 
// On met le message en gras et en italique
$messageDecore = new MessageEnItalique( new MessageEnGras( $message ) );
// On affiche le message décoré
$messageDecore->affiche();
?>

Exemple en Java[modifier | modifier le code]

// ______________________________________________________________________
// Déclarations
interface Voiture {
	public double getPrix();
}
 
class AstonMartin implements Voiture {
	@Override
	public double getPrix() {
		return 999.99;
	}
}
 
// ______________________________________________________________________
// Décorateurs
abstract class Option implements Voiture {
	protected Voiture _originale;
	protected double _tarifOption;
 
	public Option(Voiture originale, double tarif) {
		_originale = originale;
		_tarifOption += tarif;
	}
 
	@Override
	public double getPrix() {
		return _originale.getPrix() + _tarifOption;
	}
}
 
class VoitureAvecClimatisation extends Option {
	public VoitureAvecClimatisation(Voiture originale) {
		super(originale, 1.0);
	}
}
 
class VoitureAvecParachute extends Option {
	public VoitureAvecParachute(Voiture originale) {
		super(originale, 10.0);
	}
}
 
class VoitureAmphibie extends Option {
	public VoitureAmphibie(Voiture originale) {
		super(originale, 100.0);
	}
}
 
public class Usine {
	// ______________________________________________________________________
	// Implémentation
	public static void main(String[] args) {
		Voiture astonMartin = 
                new VoitureAvecClimatisation(new AstonMartin()); // Climatisation de série
		astonMartin = 
                new VoitureAvecParachute(astonMartin); // Ajout d'une option (décorateur)
		astonMartin = new VoitureAmphibie(astonMartin);
 
		System.out.println(String.format("Prix = %.2f€", astonMartin.getPrix())); 
                // affiche "Prix = 1110,99€"
	}
}

Exemple en Delphi[modifier | modifier le code]

source : Delphi GOF DesignPatterns (CodePlex)

Notes et références[modifier | modifier le code]

Annexes[modifier | modifier le code]

Articles connexes[modifier | modifier le code]

Sur les autres projets Wikimedia :