Decorator pattern

The Decorator (also Decorator ) is a design pattern in the field of software development and belongs to the category of structural patterns ( engl. structural patterns ). The pattern is a flexible alternative to subclassing to extend a class with additional functionality. It is a design pattern known as GoF patterns.

  • 2.1 The stream class of the Java library
  • 2.2 Landscape of GUI components
  • 2.3 Enhance the functionality of GUI components
  • 2.4 An example in C #

Use

The instance of a decorator is connected in front of the class to be decorated. The decorator has the same interface as the class to be decorated. Calls to the decorator are then modified or passed on unchanged ( delegation ), or they are completely processed independently. The decorator is " invisible " because the caller does not even notice that a decorator is upstream.

In an alternative variant of the decorator can be included as a strategy and called explicitly.

Actors

The abstract component defines the public interface for the objects to be decorated. The concrete component defines objects that can be decorated.

The abstract decorator holds a reference to a concrete component and provides the same interface as the abstract component. The concrete decorator defines and implements one or more special decorations.

Pros and Cons

The advantages are that several Decorators can be connected in series; decorators can be replaced at runtime, and even after instantiation. The class to be decorated is not necessarily fixed (but their interface). In addition, long and confusing inheritance hierarchies can be avoided.

The pattern has a risk: As a decorated component is not identical to the component itself (as object), you must be careful when testing for object identity. ( A comparison can go wrong, although same component is meant. ) In addition, the messages must be forwarded by the decorator to the decorated object in the use of decorated components.

Examples

The stream class of the Java library

A very nice implementation of the decorator pattern represent the stream classes in the Java library dar. They decorated the concrete stream object with objects which add new properties to the stream and can decorate on. This decorator objects can be used to add the new status information or those that provide new interfaces.

Beautify of GUI components

A text field is to be " decorated " with a frame.

Between the caller and the text field object, the corresponding Dekoriererobjekt is inserted. The Dekoriererobjekt generates the framing and passes the control flow of the text box. Since the decorator has the same interface changes from the perspective of the caller nothing.

Extending the functionality of GUI components

Each component presents itself from the origin point (0, 0); this is the real, to be decorated class. An upstream decorators can move the position by display and mouse coordinates calls are changed.

A specialization of this is a decorator, of a fixed size defined in addition, outside of which nothing can be shown. Another specialization extends the representation to a call about lying frame.

An additional decorators, who decorated the first decorator again, can make the component invisible or disabled by presentation and mouse query methods are selectively blocked.

This example can also be seen that are not mutually exclusive inheritance and delegation.

An example in C #

In an adventure game, there are pawns. Each of them can emit threats. A specific character, for example, a monster. Characters can catch cold and cough at runtime - then comes a sniffle or cough their threats ahead.

The following sample program shows how the Decorator pattern is used to verschnupfen a monster and verhusten.

It is important to understand that not the subclasses VerschnupftesMonster, VerhustetesMonster, VerschnupftesVerhustetesMonster and VerhustetesVerschnupftesMonster be formed. This approach would " mad " and " spitting fire " lead to an exponential increase in the sub-classes with the addition of further attributes like - not to mention unbearable class names as VerhustetesVerschnupftesWahnsinnigesFeuerspuckendesMonster. Only the ( sequences of ) produced decorations that are actually needed.

One sees also that the client code from the decorators knows nothing after the decorated objects have been created. From the perspective of the client code is the call to threaten always Spielfigur.Drohe ().

Using System;   namespace DekoratorMuster {        public abstract class character      {          public abstract void Drohe ();      }        public class Monster: game figure      {          public override void Drohe ()          {              Console.WriteLine (" Grrrrrrrrrr. ");          }      }        public abstract class Decorator: game figure      {          private character my character;            public Decorator ( pawn s )          {              my character = s;          }            public override void Drohe ()          {              meineFigur.Drohe ();          }      }        public class HustenDekorierer: Decorators      {          public HustenDekorierer ( s game character )             : Base ( s )          { }            public override void Drohe ()          {              Console.Write ( " Cough cough. ");              base.Drohe ();          }      }        public class SchnupfenDekorierer: Decorators      {          public SchnupfenDekorierer ( s game character )             : Base ( s )          { }            public override void Drohe ()          {              Console.Write ( " Schniff. ");              base.Drohe ();          }      }        public class client code      {          public static void Main ()          {              Pawn my monster = new Monster ();              meinMonster.Drohe ();                Character meinVerhustetesMonster = new HustenDekorierer (my monster );              meinVerhustetesMonster.Drohe ();                Character meinVerschnupftesMonster = new SchnupfenDekorierer (my monster );              meinVerschnupftesMonster.Drohe ();                Character meinVerschnupftesVerhustetesMonster = new SchnupfenDekorierer (new HustenDekorierer (my monster ) );              meinVerschnupftesVerhustetesMonster.Drohe ();                Character meinVerhustetesVerschnupftesMonster = new HustenDekorierer (new SchnupfenDekorierer (my monster ) );              meinVerhustetesVerschnupftesMonster.Drohe ();          }      } } The output of this program is:

Grrrrrrrrr. Cough cough. Grrrrrrrrrr. Schniff. Grrrrrrrrrr. Schniff. Cough cough. Grrrrrrrrrr. Cough cough. Schniff. Grrrrrrrrrr. Similarly, examples in C and other object-oriented programming languages ​​can be created.

Related Patterns

Compared to the decorator, which selects the class actually used themselves, the invoker must explicitly know which variants are available and which one to use it in the Strategy pattern.

Similar to the decorator is also still the Composite pattern.

225019
de