Decoration mode: Decorator (converted from a. NET)

Source: Internet
Author: User
Decorator Mode

Decorator mode, also known as Wrapper mode [GOF95]. The decoration mode extends the object functions in a transparent way to the client. It is an alternative to the inheritance relationship.

Introduction

Sun Wukong has a change, and each of his changes brings him an additional skill. When he becomes a fish, he can swim in the water; when he becomes a sparrow, he can fly in the sky. However, no matter how Wukong changes, in the eyes of Erlang, he will always be the hacker.

The decoration mode dynamically attaches more responsibilities to an object in a transparent manner to the customer. In other words, the client does not think that objects are different before and after decoration. The decoration mode can extend the functions of objects without creating more child classes.

Ii. Structure of the decoration Mode

The decoration mode uses an instance of a subclass of the originally decorated class to delegate the call of the client to the decorated class. The key to the decoration mode is that the extension is completely transparent.

In the example of Sun monkey, the old sun becomes a child of the old sun. The interaction between the old Sun and the outside world should be "delegated", handed over to the old sun, and the old sun will take action.

Shows the decoration mode class diagram:

In the decoration mode, the roles are:

Abstract Component role: provides an abstract interface to standardize the objects that are prepared to receive additional responsibilities.
Concrete Component role: defines a class that will receive additional responsibilities.
Decorator: holds an instance of a Component object and defines an interface consistent with the abstract Component Interface.
Concrete Decorator: attaches "additional responsibilities to the component object.

3. decoration mode DEMO code

The following DEMO code implements the decoration Mode

// Decorator pattern -- Structural example  using System;// "Component"abstract class Component{  // Methods  abstract public void Operation();}// "ConcreteComponent"class ConcreteComponent : Component{  // Methods  override public void Operation()  {    Console.WriteLine("ConcreteComponent.Operation()");  }}// "Decorator"abstract class Decorator : Component{  // Fields  protected Component component;  // Methods  public void SetComponent( Component component )  {    this.component = component;  }  override public void Operation()  {    if( component != null )      component.Operation();  }}// "ConcreteDecoratorA"class ConcreteDecoratorA : Decorator{  // Fields  private string addedState;  // Methods  override public void Operation()  {    base.Operation();    addedState = "new state";    Console.WriteLine("ConcreteDecoratorA.Operation()");  }}// "ConcreteDecoratorB"class ConcreteDecoratorB : Decorator{  // Methods  override public void Operation()  {    base.Operation();    AddedBehavior();    Console.WriteLine("ConcreteDecoratorB.Operation()");  }  void AddedBehavior()  {  }}/**//// <summary>/// Client test/// </summary>public class Client{  public static void Main( string[] args )  {    // Create ConcreteComponent and two Decorators    ConcreteComponent c = new ConcreteComponent();    ConcreteDecoratorA d1 = new ConcreteDecoratorA();    ConcreteDecoratorB d2 = new ConcreteDecoratorB();    // Link decorators    d1.SetComponent( c );    d2.SetComponent( d1 );    d2.Operation();  }}

The above code is implemented through the SetComponent method during decoration execution. In actual applications, it is also implemented through constructors. A typical creation process may be as follows:

new Decorator1(   new Decorator2(      new Decorator3(         new ConcreteComponent()         )      )   )

The decoration mode is often called the package mode because each specific decoration class wraps the next specific decoration class or specific component class.

4. Where should I use the decoration mode?

The decoration mode should be used in the following circumstances:

You need to expand the functions of a class or add additional responsibilities to a class.
You need to dynamically add functions to an object. These functions can be dynamically revoked.
A large number of functions are generated by the arrangement and combination of some basic functions to make the inheritance relationship unrealistic.

5. Example of practical application of decoration Mode

This example demonstrates how to add "loose" decoration to library books and video tapes in decoration mode.

// Decorator pattern -- Real World example  using System;using System.Collections;// "Component"abstract class LibraryItem{  // Fields  private int numCopies;  // Properties  public int NumCopies  {    get{ return numCopies; }    set{ numCopies = value; }  }  // Methods  public abstract void Display();}// "ConcreteComponent"class Book : LibraryItem{  // Fields  private string author;  private string title;  // Constructors  public Book(string author,string title,int numCopies)  {    this.author = author;    this.title = title;    this.NumCopies = numCopies;  }  // Methods  public override void Display()  {    Console.WriteLine( " Book ------ " );    Console.WriteLine( " Author: {0}", author );    Console.WriteLine( " Title: {0}", title );    Console.WriteLine( " # Copies: {0}", NumCopies );  }}// "ConcreteComponent"class Video : LibraryItem{  // Fields  private string director;  private string title;  private int playTime;  // Constructor  public Video( string director, string title,    int numCopies, int playTime )  {    this.director = director;    this.title = title;    this.NumCopies = numCopies;    this.playTime = playTime;  }  // Methods  public override void Display()  {    Console.WriteLine( " Video ----- " );    Console.WriteLine( " Director: {0}", director );    Console.WriteLine( " Title: {0}", title );    Console.WriteLine( " # Copies: {0}", NumCopies );    Console.WriteLine( " Playtime: {0}", playTime );  }}// "Decorator"abstract class Decorator : LibraryItem{  // Fields  protected LibraryItem libraryItem;  // Constructors  public Decorator ( LibraryItem libraryItem )  { this.libraryItem = libraryItem; }  // Methods  public override void Display()  { libraryItem.Display(); }}// "ConcreteDecorator"class Borrowable : Decorator{  // Fields  protected ArrayList borrowers = new ArrayList();  // Constructors  public Borrowable( LibraryItem libraryItem )    : base( libraryItem ) {}  // Methods  public void BorrowItem( string name )  {    borrowers.Add( name );    libraryItem.NumCopies--;  }  public void ReturnItem( string name )  {    borrowers.Remove( name );    libraryItem.NumCopies++;  }  public override void Display()  {    base.Display();    foreach( string borrower in borrowers )      Console.WriteLine( " borrower: {0}", borrower );  }} /**//// <summary>///  DecoratorApp test/// </summary>public class DecoratorApp{  public static void Main( string[] args )  {    // Create book and video and display    Book book = new Book( "Schnell", "My Home", 10 );    Video video = new Video( "Spielberg",      "Schindler's list", 23, 60 );    book.Display();    video.Display();    // Make video borrowable, then borrow and display    Console.WriteLine( " Video made borrowable:" );    Borrowable borrowvideo = new Borrowable( video );    borrowvideo.BorrowItem( "Cindy Lopez" );    borrowvideo.BorrowItem( "Samuel King" );    borrowvideo.Display();  }}

Vi. advantages and disadvantages of using the decoration Mode

The decoration mode has the following advantages:

The purpose of the relationship between the decoration mode and inheritance is to expand the object functions, but the decoration mode can provide more flexibility than inheritance.
By using different specific decorative classes and the arrangement and combination of these decorative classes, designers can create a combination of many different behaviors.
This is more flexible than inheritance, and it also means that the decoration mode is more error-prone than inheritance.
The decoration mode has the following Disadvantages:

Because the decorative mode is used, there are a few categories that are needed than the inheritance relationship. Use fewer classes, of course, make the design easier. However, on the other hand, the use of decoration mode will produce more objects than the use of inheritance relationships. More objects make it difficult to query errors, especially those objects look very similar.

7. Discussion on model implementation

In most cases, the implementation of the decoration mode is simpler than the schematic implementation given in the above definition. Note the following when simplifying the mode:

(1) the interface of a decoration class must be compatible with the interface of the decoration class.

(2) Try to keep Component as a "light" class. Do not put too much logic and status in the Component class.

(3) If there is only one ConcreteComponent class but no abstract Component class (Interface), the Decorator class can often be a subclass of ConcreteComponent. As shown in:


(4) If there is only one ConcreteDecorator class, there is no need to create a separate Decorator class. Instead, you can combine the responsibilities of Decorator and ConcreteDecorator into one class.

VIII. Transparency requirements

Transparent decoration Mode

The decoration mode usually requires abstract programming. The transparency of the decoration mode on the client requires that the program declare a variable of the ConcreteDecorator type instead of a variable of the Component type. In other words, the following method is correct:

Component c = new ConcreteComponent();Component c1 = new ConcreteDecorator1(c);Component c2 = new ConcreteDecorator(c1);

The following method is incorrect:

ConcreteComponent c = new ConcreteDecorator();

This is what we mentioned above. The decoration mode is completely transparent to the client.

In the example of Sun Wukong, all the changes made by Sun Wukong must always be treated as Sun Wukong. If he regards the old grandson as a child rather than a child, he will be cheated by the old grandson, this should not happen.

The following method is incorrect:

Grand Saint c =NewGrand sage (); sparrow bird =NewQue Er (c );

Translucent decoration Mode

However, the pure decoration mode is hard to find. The purpose of the decoration mode is to enhance the performance of the classes to be considered without changing the interface. When enhancing performance, new public methods are often required. Even in Sun dasheng's system, new methods are needed. For example, qitian dasheng does not have the flight capability, but queer does. This means that que should have a new fly () method.

This leads to the implementation of most decoration modes being "semi-transparent" rather than completely "transparent. In other words, allow the decoration mode to change the interface and add new methods. Declare the variables of the ConcreteDecorator type, so that you can call the methods in the ConcreteDecorator class:

Qi tianda c =NewGrand sage (); sparrow bird =NewQue Er (c); bird. fly ();

The Qi tiandasheng interface does not have the fly () method at all, but the que ER interface does.

9. Application of decoration mode in. NET

. Net has the following class model:


The following code snippet is used to output the content format of XmlDocument. We can understand the role of the Decorator mode.

Copy and save

// Generate ConcreteComponent (memory stream ms)MemoryStream MS =NewMemoryStream ();// Use XmlTextWriter to decorate the memory stream MS// The translucent decoration mode is used hereXmlTextWriter xtw =NewXmlTextWriter (MS, Encoding. UTF8); xtw. Formatting = Formatting. Indented;// The operation on the decoration xtw will switch to the Ontology-memory stream msXmlDoc. Save (xtw );Byte[] Buf = ms. ToArray (); txtResult. Text = Encoding. UTF8.GetString (buf, 0, buf. Length); xtw. Close ();

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.