Decorator Design Pattern

By Peter Bromberg

Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

using System;
using System.Collections.Generic;

namespace Patterns
{
  
    
class MainApp
    {
         
        
static void Main()
        {
             
// Create book
            Book book =
new Book("Worley", "Inside ASP.NET", 10);
            book.
Display();

             
// Create video
            Video video =
new Video("Spielberg", "Jaws", 23, 92);
             video.
Display();

             
// Make video borrowable, then borrow and display
          
Console.WriteLine("\nMaking video borrowable:");

            Borrowable borrowvideo =
new Borrowable(video);
             borrowvideo.BorrowItem(
"Customer #1");
            borrowvideo.BorrowItem(
"Customer #2");

             borrowvideo.
Display();

             
// Wait for user
          
Console.ReadKey();
        }
     }

    
/// <summary>
    
/// The 'Component' abstract class
    
/// </summary>
    
abstract class LibraryItem
    {
         
public int NumCopies { get; set; }

         
public abstract void Display();
    }

    
/// <summary>
    
/// The 'ConcreteComponent' class
    
/// </summary>
    
class Book : LibraryItem
    {
         
private string _author;
        
private string _title;

        
// Constructor
        public Book(string author, string title, int numCopies)
        {
             
this._author = author;
             
this._title = title;
             
this.NumCopies = numCopies;
        }

        
public override void Display()
        {
          
Console.WriteLine("\nBook ------ ");
          
Console.WriteLine(" Author: {0}", _author);
          
Console.WriteLine(" Title: {0}", _title);
          
Console.WriteLine(" # Copies: {0}", NumCopies);
        }
     }

    
/// <summary>
    
/// The 'ConcreteComponent' class
    
/// </summary>
    
class Video : LibraryItem
    {
         
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;
        }

        
public override void Display()
        {
          
Console.WriteLine("\nVideo ----- ");
          
Console.WriteLine(" Director: {0}", _director);
          
Console.WriteLine(" Title: {0}", _title);
          
Console.WriteLine(" # Copies: {0}", NumCopies);
          
Console.WriteLine(" Playtime: {0}\n", _playTime);
        }
     }

    
/// <summary>
    
/// The 'Decorator' abstract class
    
/// </summary>
    
abstract class Decorator : LibraryItem
    {
         
protected LibraryItem libraryItem;

         
// Constructor
        public Decorator(LibraryItem libraryItem)
        {
            
this.libraryItem = libraryItem;
        }

        
public override void Display()
        {
             libraryItem.
Display();
        }
     }

    
/// <summary>
    
/// The 'ConcreteDecorator' class
    
/// </summary>
    
class Borrowable : Decorator
    {
        
protected List<string> borrowers = new List<string>();

        
// Constructor
        public Borrowable(LibraryItem libraryItem)
            :
base(libraryItem)
        {
         }

         
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: " + borrower);
             }
        }
     }
}

Decorator Design Pattern  (263 Views)
Create New Account