11
2010
Design Patterns : Decorator pattern
Intent
- Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub-classing for extending functionality. [GoF, p175]
- Client-specified embellishment of a core object recursively wrapping it.
Diagram

Rules of thumb
- Adapter provides a different interface to its subject. Proxy provides the same interface. but the decorator provides an enhanced interface. [Gof, p216]
- Adopter changes an object’s interface, Decorator enhances an objects responsibilities, Decorator is thus more transparent to the client. As a consequence, decorator supports recursive composition, which isn’t possible with pure adapters. [GoF, p149]
- Composite and decorator have similar structure diagrams, reflecting the fact that both rely on recursive composition to organize an open-ended number of objects [GoF, p219]
- A decorator can be viewed as a degenerate composite with only one component. however, a decorator adds additional responsibilities – it isn’t intended for object aggregation. [GoF, p184]
- Decorator is designed to let you add responsibilities to objects without sub-classing. Composite focus is not on embellishment but on representation. These intents are distinct but complementary. Consequently, composite and decorator are often used in concert. [GoF, p220]
- Composite could use Chain of Responsibility to let components access global properties through their parent. It could also use Decorator to override these properties on parts of the composition. [GoF, p349]
- Decorator and Proxy have different purposes but similar structures. Both describe how to provide a level of indirection to another object, and the implementations keep a reference to the object to which they forward requests. [GoF, p220]
- Decorator lets you change the skin of an object. Strategy lets you change the guts. [GoF, p184]
Code Sample
using System;
using System.Collections.Generic;
namespace DoFactory.GangOfFour.Decorator.RealWorld
{
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 {
private int _numCopies;
// Property
public int NumCopies
{
get { return _numCopies; }
set { _numCopies = value; }
}
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);
}
}
}
}
Related Posts
Recent Posts
- How to populate a dropdown menu from database in CodeIgniter [Workaround]
- How to Overclock Samsung Galaxy Mini Upto 800MHz
- Current and Future Relavance of Business Excellence / Improvement to Argos UK Ltd. Possible Benefits and Likely Inhabitors Exists
- What can Harm Your Online Reputation?
- Does Race Matter in the Choice of Popular Music among Youngsters?
The Tutebox
- Accounting
- Android Tips
- Apps
- Business
- C / C++
- Computers
- Database
- Design Patterns
- E-Commerce
- Economics
- Electronics
- Entertainment
- Finance
- Functional Programming
- Games
- Hardware
- Health
- HRM
- International Business
- Internet
- iOS Tips
- JAVA
- Life Style
- Linux
- M-Commerce
- Management
- Marketing
- Mathematics
- Mobile
- MS Office
- Network
- PC
- Personal Development
- Photography
- PHP
- Physics
- Places
- Programming
- Science
- Software
- Statistics
- Tweaks
- Visual Studio
- Web Hosting
- Windows

Article by




