72 votes

Quand utiliser le motif décorateur?

Je passe en revue mes modèles de conception, et un modèle que je n'ai pas encore sérieusement utilisé dans mon codage est le modèle de décorateur.

Je comprends le motif, mais ce que j'aimerais savoir, ce sont de bons exemples concrets de fois dans le monde réel où le motif décorateur est la meilleure solution / optimale / élégante. Situations spécifiques où le besoin du motif décorateur est vraiment pratique.

Merci.

88voto

Pascal Thivent Points 295221

Le Décorateur Modèle est utilisé pour ajouter des fonctionnalités supplémentaires à un objet particulier, par opposition à une classe d'objets. Il est facile d'ajouter des fonctionnalités à une classe entière d'objets par sous-classement d'un objet, mais il est impossible d'étendre un objet unique de cette manière. Avec le Décorateur Modèle, vous pouvez ajouter des fonctionnalités à un objet unique et de laisser d'autres comme ça, non modifiée.

En Java, un exemple classique de le décorateur motif est la Java I/O Flux de mise en œuvre.

FileReader       frdr = new FileReader(filename);
LineNumberReader lrdr = new LineNumberReader(frdr);

Le code ci-dessus crée un lecteur -- lrdr -- qui lit un fichier et de pistes pour les numéros de ligne. Ligne 1 crée un lecteur de fichiers (frdr), et la ligne 2 ajoute de la ligne numéro de suivi.

En fait, j'aimerais vous encourage fortement à regarder le code source Java pour Java I/O classes.

43voto

Charlie Salts Points 5958

Le motif décorateur est beaucoup utilisé avec les flux: vous pouvez envelopper un flux avec un flux pour obtenir des fonctionnalités supplémentaires. J'ai vu cela avec le framework .Net - pour autant que je sache, cela se produit ailleurs. Mon préféré est d'utiliser GZipStream autour d'un FileStream, pour une compression supplémentaire.

38voto

Kaleb Brasee Points 25776

J'ai récemment utilisé le décorateur de motif dans un service web qui utilise les éléments suivants CommandProcessor interface:

public Command receive(Request request);
public Response execute(Command command);
public void respond(Response response);

Fondamentalement, la CommandProcessor reçoit une Demande et crée le bon de Commande, exécute la Commande et crée la Réponse appropriée, et envoie la Réponse. Quand j'ai voulu ajouter un calendrier et journal, j'ai créé un TimerDecorator qui a utilisé un existant CommandProcessor que sa composante. Le TimerDecorator implémente CommandProcessor interface, mais ajoute juste le timing, puis appelle sa cible, qui est le véritable CommandProcessor. Quelque chose comme ceci:

public class TimerDecorator implements CommandProcessor {
   private CommandProcessor target;
   private Timer timer;

   public TimerDecorator(CommandProcessor processor) {
      this.target = processor;
      this.timer = new Timer();
   }

   public Command receive(Request request) {
      this.timer.start();
      return this.target.receive(request);
   }

   public Response execute(Command command) {
      return this.target.execute(command);
   }

   public void respond(Response response) {
      this.target.response(response);
      this.timer.stop();
      // log timer
   }

}

Donc le vrai CommandProcessor est enveloppé à l'intérieur TimerDecorator, et je peux traiter TimerDecorator tout comme la cible CommandProcessor, mais maintenant timing logique a été ajouté.

7voto

Michael Valenty Points 5482

Le décorateur est simple mais extrêmement puissant. C'est un facteur clé dans la réalisation de la séparation des préoccupations et est un outil essentiel pour l'Ouvrir Fermé Principal. Un exemple de placer une commande pour un produit:

IOrderGateway
{
    void PlaceOrder(Order order);
{

Principale application: AmazonAffiliateOrderGateway

Possible décorateurs pourrait être:

  • IncrementPerformanceCounterOrderGateway
  • QueueOrderForLaterOnTimeoutOrderGateway
  • EmailOnExceptionOrderGateway
  • InterceptTestOrderAndLogOrderGateway

Jetez un oeil ici pour un exemple plus détaillé.

4voto

Mike B Points 18950

Zend Framework utilise le décorateur pour les éléments de formulaire

Quelques informations supplémentaires: http://framework.zend.com/manual/en/zend.form.decorators.html

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X