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  (713 Views)