Design Pattern - Decorator(C#)
阿新 • • 發佈:2018-11-02
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
Definition
Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
Participants
The classes and/or objects participating in this pattern are:
- Component (LibraryItem)
- Defines the interface for objects that can have responsibilities added to them dynamically.
- ConcreteComponent (Book, Video)
- Defines an object to which additional responsibilities can be attached.
- Defines an object to which additional responsibilities can be attached.
- Decorator (Decorator)
- Maintains a reference to a Component object and defines an interface that conforms to Component's interface.
- ConcreteDecorator (Borrowable)
- Adds responsibilities to the component.
Sample Code in C#
This structural code demonstrates the Decorator pattern which dynamically adds extra functionality to an existing object.
// --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Structural Decorator Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{ using System; /// <summary> /// Startup class for Structural Decorator Design Pattern. /// </summary> internal static class Program { #region Methods /// <summary> /// Entry point into console application. /// </summary> private static void Main() { // Create ConcreteComponent and two Decorators var c = new ConcreteComponent(); var d1 = new ConcreteDecoratorA(); var d2 = new ConcreteDecoratorB(); // Link decorators d1.SetComponent(c); d2.SetComponent(d1); d2.Operation(); } #endregion } /// <summary> /// The 'Component' abstract class /// </summary> internal abstract class Component { #region Public Methods and Operators /// <summary> /// The operation. /// </summary> public abstract void Operation(); #endregion } /// <summary> /// The 'ConcreteComponent' class /// </summary> internal class ConcreteComponent : Component { #region Public Methods and Operators /// <summary> /// The operation. /// </summary> public override void Operation() { Console.WriteLine("ConcreteComponent.Operation()"); } #endregion } /// <summary> /// The 'Decorator' abstract class /// </summary> internal abstract class Decorator : Component { #region Fields /// <summary> /// The component. /// </summary> protected Component Component; #endregion #region Public Methods and Operators /// <summary> /// The operation. /// </summary> public override void Operation() { if (this.Component != null) { this.Component.Operation(); } } /// <summary> /// The set component. /// </summary> /// <param name="component"> /// The component. /// </param> public void SetComponent(Component component) { this.Component = component; } #endregion } /// <summary> /// The 'ConcreteDecoratorA' class /// </summary> internal class ConcreteDecoratorA : Decorator { #region Public Methods and Operators /// <summary> /// The operation. /// </summary> public override void Operation() { base.Operation(); Console.WriteLine("ConcreteDecoratorA.Operation()"); } #endregion } /// <summary> /// The 'ConcreteDecoratorB' class /// </summary> internal class ConcreteDecoratorB : Decorator { #region Public Methods and Operators /// <summary> /// The operation. /// </summary> public override void Operation() { base.Operation(); this.AddedBehavior(); Console.WriteLine("ConcreteDecoratorB.Operation()"); } #endregion #region Methods /// <summary> /// The added behavior. /// </summary> private void AddedBehavior() { } #endregion }}// Output:/*ConcreteComponent.Operation()ConcreteDecoratorA.Operation()ConcreteDecoratorB.Operation()*/
This real-world code demonstrates the Decorator pattern in which 'borrowable' functionality is added to existing library items (books and videos).
// --------------------------------------------------------------------------------------------------------------------// <copyright company="Chimomo's Company" file="Program.cs">// Respect the work.// </copyright>// <summary>// Real-World Decorator Design Pattern.// </summary>// --------------------------------------------------------------------------------------------------------------------namespace CSharpLearning{ using System; using System.Collections.Generic; /// <summary> /// Startup class for Real-World Decorator Design Pattern. /// </summary> internal static class Program { #region Methods /// <summary> /// Entry point into console application. /// </summary> private static void Main() { // Create book var book = new Book("Worley", "Inside ASP.NET", 10); book.Display(); // Create video var video = new Video("Spielberg", "Jaws", 23, 92); video.Display(); // Make video borrowable, then borrow and display Console.WriteLine("\nMaking video borrowable:"); var borrowvideo = new Borrowable(video); borrowvideo.BorrowItem("Customer #1"); borrowvideo.BorrowItem("Customer #2"); borrowvideo.Display(); } #endregion } /// <summary> /// The 'Component' abstract class /// </summary> internal abstract class LibraryItem { // Property #region Public Properties /// <summary> /// Gets or sets the number of copies. /// </summary> public int NumCopies { get; set; } #endregion #region Public Methods and Operators /// <summary> /// The display. /// </summary> public abstract void Display(); #endregion } /// <summary> /// The 'ConcreteComponent' class /// </summary> internal class Book : LibraryItem { #region Fields /// <summary> /// The author. /// </summary> private string author; /// <summary> /// The title. /// </summary> private string title; #endregion // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="Book"/> class. /// </summary> /// <param name="author"> /// The author. /// </param> /// <param name="title"> /// The title. /// </param> /// <param name="numCopies"> /// The number of copies. /// </param> public Book(string author, string title, int numCopies) { this.author = author; this.title = title; this.NumCopies = numCopies; } #endregion #region Public Methods and Operators /// <summary> /// The display. /// </summary> public override void Display() { Console.WriteLine("\nBook ------ "); Console.WriteLine(" Author: {0}", this.author); Console.WriteLine(" Title: {0}", this.title); Console.WriteLine(" # Copies: {0}", this.NumCopies); } #endregion } /// <summary> /// The 'ConcreteComponent' class /// </summary> internal class Video : LibraryItem { #region Fields /// <summary> /// The director. /// </summary> private string director; /// <summary> /// The play time. /// </summary> private int playTime; /// <summary> /// The title. /// </summary> private string title; #endregion // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="Video"/> class. /// </summary> /// <param name="director"> /// The director. /// </param> /// <param name="title"> /// The title. /// </param> /// <param name="numCopies"> /// The number of copies. /// </param> /// <param name="playTime"> /// The play time. /// </param> public Video(string director, string title, int numCopies, int playTime) { this.director = director; this.title = title; this.NumCopies = numCopies; this.playTime = playTime; } #endregion #region Public Methods and Operators /// <summary> /// The display. /// </summary> public override void Display() { Console.WriteLine("\nVideo ----- "); Console.WriteLine(" Director: {0}", this.director); Console.WriteLine(" Title: {0}", this.title); Console.WriteLine(" # Copies: {0}", this.NumCopies); Console.WriteLine(" Playtime: {0}\n", this.playTime); } #endregion } /// <summary> /// The 'Decorator' abstract class /// </summary> internal abstract class Decorator : LibraryItem { #region Fields /// <summary> /// The library item. /// </summary> protected readonly LibraryItem LibraryItem; #endregion // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="Decorator"/> class. /// </summary> /// <param name="libraryItem"> /// The library item. /// </param> protected Decorator(LibraryItem libraryItem) { this.LibraryItem = libraryItem; } #endregion #region Public Methods and Operators /// <summary> /// The display. /// </summary> public override void Display() { this.LibraryItem.Display(); } #endregion } /// <summary> /// The 'ConcreteDecorator' class /// </summary> internal class Borrowable : Decorator { #region Fields /// <summary> /// The borrowers. /// </summary> protected readonly List<string> Borrowers = new List<string>(); #endregion // Constructor #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="Borrowable"/> class. /// </summary> /// <param name="libraryItem"> /// The library item. /// </param> public Borrowable(LibraryItem libraryItem) : base(libraryItem) { } #endregion #region Public Methods and Operators /// <summary> /// The borrow item. /// </summary> /// <param name="name"> /// The name. /// </param> public void BorrowItem(string name) { this.Borrowers.Add(name); this.LibraryItem.NumCopies--; } /// <summary> /// The display. /// </summary> public override void Display() { base.Display(); foreach (string borrower in this.Borrowers) { Console.WriteLine(" borrower: " + borrower); } } /// <summary> /// The return item. /// </summary> /// <param name="name"> /// The name. /// </param> public void ReturnItem(string name) { this.Borrowers.Remove(name); this.LibraryItem.NumCopies++; } #endregion }}// Output:/*Book ------ Author: Worley Title: Inside ASP.NET # Copies: 10Video ----- Director: Spielberg Title: Jaws # Copies: 23 Playtime: 92Making video borrowable:Video ----- Director: Spielberg Title: Jaws # Copies: 21 Playtime: 92 borrower: Customer #1 borrower: Customer #2*/