Object Oriented Programming Patterns for Geeks
The Decorator Pattern
namespace ooppatterns
{
using System;
using System.Collections.Generic;
internal class Program
{
private static void Main( string[] args )
{
// Instantiate the client
IReportRenderer report = new ReportGenerator();
// Now 'decorate' it
IReportPart head = new Header( "A Report" );
head.Append( new Paragraph( "By Moridin8" ) );
report.Append( head );
IReportPart title = new Title();
title.Text = "A Decorator in Action";
title.Append( new TextLine( " - OOP rules!!" ) );
report.Append( title );
IReportPart body = new Paragraph();
body.Text = @"Lorem ipsum dolor sit amet,"
+ @"consectetuer adipiscing elit. "
+ @"Morbi at nunc malesuada erat "
+ "varius venenatis. Suspendisse eget orci.";
report.Append( body );
body = new Paragraph();
body.Text = @"Vestibulum rhoncus. Nunc ornare metus. "
+ @"Ut quam. In ante massa, hendrerit at, "
+ @"facilisis id";
report.Append( body );
IReportPart foot = new Footer( "Page 1" );
report.Append( foot );
// Make the client object use the decorations...
report.Render();
Console.ReadLine();
}
}
// Client object and interfaces
interface IReportRenderer
{
void Append( IReportPart part );
void Render();
}
interface IReportPart : IReportRenderer
{
string Text { get; set; }
}
class ReportGenerator : IReportRenderer
{
private List<IReportPart> _parts = new List<IReportPart>();
public void Append( IReportPart part )
{
this._parts.Add( part );
}
public void Render()
{
foreach ( IReportPart iRP in this._parts )
iRP.Render();
}
}
// Decorators for the Client object to be 'decorated' with.
class Header : IReportPart
{
private List<IReportPart> _parts = new List<IReportPart>();
private string _text;
public Header( string text )
{
this._text = text;
}
public string Text
{
get { return this._text; }
set { this._text = value; }
}
public void Append( IReportPart part )
{
this._parts.Add( part );
}
public void Render()
{
Console.WriteLine( new string( '=', 20 ) );
Console.WriteLine( this._text );
if ( this._parts.Count > 0 )
foreach ( IReportPart iRP in this._parts )
iRP.Render();
Console.WriteLine( new string( '~', 20 ) );
}
}
class Title : IReportPart
{
private List<IReportPart> _parts = new List<IReportPart>();
private string _text;
public string Text
{
get { return this._text; }
set { this._text = value; }
}
public void Render()
{
int addtolen = 0;
Console.WriteLine();
Console.Write( this._text );
if ( this._parts.Count > 0 )
foreach ( IReportPart iRP in this._parts )
{
addtolen += iRP.Text.Length;
iRP.Render();
}
Console.WriteLine();
Console.WriteLine( new string( '-', this._text.Length + addtolen + 1 ) );
Console.WriteLine();
}
public void Append( IReportPart part )
{
if ( part is TextLine )
this._parts.Add( part );
}
}
class Paragraph : IReportPart
{
private string _text;
public Paragraph() { }
public Paragraph( string text )
{
this._text = text;
}
public string Text
{
get { return this._text; }
set { this._text = value; }
}
public void Render()
{
Console.WriteLine( this._text );
Console.WriteLine();
}
public void Append( IReportPart part ) { } // not implemented
}
class TextLine : IReportPart
{
private string _text;
public TextLine( string text )
{
this._text = text;
}
public string Text
{
get { return this._text; }
set { this._text = value; }
}
public void Render()
{
Console.Write( this._text );
}
public void Append( IReportPart part ) { } // not implemented
}
class Footer : IReportPart
{
private List<IReportPart> _parts = new List<IReportPart>();
private string _text;
public Footer( string text )
{
this._text = text;
}
public string Text
{
get { return this._text; }
set { this._text = value; }
}
public void Append( IReportPart part )
{
this._parts.Add( part );
}
public void Render()
{
Console.WriteLine( new string( '~', 20 ) );
Console.WriteLine( this._text );
if ( this._parts.Count > 0 )
foreach ( IReportPart iRP in this._parts )
iRP.Render();
Console.WriteLine( new string( '=', 20 ) );
}
}
}