Decorator Pattern Example
Hi Folks,
I'm trying to learn the Decorator Pattern. Can someone help with this code. The following code displays an image
// The original Photo class public class Photo : Form{
Image image; public Photo(){
image =
new Bitmap("jug.jpg"); this.Text = "Lemonade"; this.Paint += new PaintEventHandler(Drawer);}
public void Drawer(Object source, PaintEventArgs e){
e.Graphics.DrawImage(image, 30, 20);
}
private void InitializeComponent(){
this.SuspendLayout(); // // Photo // this.ClientSize = new System.Drawing.Size(283, 250); this.Name = "Photo"; this.ResumeLayout(false);}
}
I want to use the decorator pattern so that I can put a border on the image. Can someone please help me?
Would greatly appreciate your help.
thanks,
John
Answers
Martin,
This is what I came up with:
//**********************************************************
// Answer to decorator_pattern excercise 1
//**********************************************************
class
DecoratorPatternExcercise_1{
public interface IPhoto{
void Drawer(Object source, PaintEventArgs e);}
// The original Photo class public class Photo : Form, IPhoto{
Image image; public Photo(){
image =
new Bitmap("jug.jpg"); this.Text = "Lemonade"; this.Paint += new PaintEventHandler(Drawer);}
public void Drawer(Object source, PaintEventArgs e){
e.Graphics.DrawImage(image, 30, 20);
}
private void InitializeComponent(){
this.SuspendLayout(); // // Photo // this.ClientSize = new System.Drawing.Size(283, 250); this.Name = "Photo"; this.ResumeLayout(false);}
}
// This simple BorderedPhoto decorator adds a colored BorderedPhoto of fixed size class BorderedPhoto :Form, IPhoto{
IPhoto photo; Color color; public BorderedPhoto(IPhoto p, Color c){
photo = p;
color = c;
this.Paint += new PaintEventHandler(Drawer);}
public void Drawer(Object source, PaintEventArgs e){
photo.Drawer(source, e);
e.Graphics.DrawRectangle(
new Pen(color, 10), 25, 15, 215, 225);}
}
//// The TaggedPhoto decorator keeps track of the tag number which gives it //// a specific place to be written class TaggedPhoto : Form, IPhoto{
IPhoto photo; string tag; int number; static int count; List<string> tags = new List<string>(); public TaggedPhoto(IPhoto p, string t){
photo = p;
tag = t;
tags.Add(t);
number = ++count;
this.Paint += new PaintEventHandler(Drawer);}
public void Drawer(Object source, PaintEventArgs e){
photo.Drawer(source, e);
e.Graphics.DrawString(tag,
new Font("Arial", 16), new SolidBrush(Color.Black), new PointF(80, 100 + number * 20));}
public string ListTaggedPhotos(){
string s = "Tags are: "; foreach (string t in tags) s += t + " "; return s;}
}
static void Main(){
//// Application.Run acts as a simple client IPhoto photo; TaggedPhoto foodTaggedPhoto, colorTaggedPhoto, tag; BorderedPhoto composition; //// Compose a photo with two TaggedPhotos and a blue BorderedPhotophoto =
new Photo(); //Application.Run(photo);foodTaggedPhoto =
new TaggedPhoto(photo, "Food");colorTaggedPhoto =
new TaggedPhoto(foodTaggedPhoto, "Yellow");composition =
new BorderedPhoto(colorTaggedPhoto, Color.Blue); Application.Run(composition); //Console.WriteLine(colorTaggedPhoto.ListTaggedPhotos()); //// Compose a photo with one TaggedPhoto and a yellow BorderedPhotophoto =
new Photo();tag =
new TaggedPhoto(photo, "Jug");composition =
new BorderedPhoto(tag, Color.Yellow); Application.Run(composition); //Console.WriteLine(tag.ListTaggedPhotos());}
}
I don't know if that's the best practice, but it sure did solve the problem!! Thanks for your help.
John
John,
I can see something that doesn't gel between the two implementations, that's the derivation from a form class.
Using your first example to illustrate, I'd say that the form is implemented by 'Component' only, then the instance of the component is injected into the decorator classes. In that way you have only one instance of a form floating around, and you follow the pattern too.
Well done though, patterns aren't the easiest thing to get your head around in a real situation.
If you found my work helpful could you please mark MY post as helpful too?

Thanks,
Martin Platt.
All Replies
John,
I'm not really sure that you're understanding the purpose of the pattern, unless of course there's more information on what you're planning to do, that you're holding back?
The pattern is based around the idea that you have an implementation that performs some basic functionality, and then different decorators add to that functionality. Whilst it would be overkill, you could make different decorators draw different coloured borders around the picture, for instance. If you just have one border to draw, then there's no point, just add the code to the drawer object, unless there's some reason to suspect that this additional behaviour is likely to different in the future.
I suspect that you're trying to make the development fit the pattern rather than the other way around?
A good place to read, if you haven't read it is:
http://www.dofactory.com/Patterns/PatternDecorator.aspx
http://en.wikipedia.org/wiki/Decorator_pattern
I know that I didn't exaclty answer your question, but I'd rather make sure that you're aware of why you'd use the pattern before you use it?
If you have a reason for doing this, please exand on your example.
Hope this helps,
Martin Platt.
Hey Martin,
Thanks for the reply.
I'm actually reading this book 'C# Design Patterns' and at the end of the 'Decorator pattern' section, there is an excercise about adding a border around the image displayed in the above example using the 'Decorator Pattern'.
Yes I do understand the 'Decorator Pattern' well and here's an example that I did:
interface IComponent{
string Operation();}
class Component : IComponent{
public string Operation(){
return "I am walking ";}
}
class DecoratorA : IComponent{
IComponent component; public DecoratorA(IComponent c){
component = c;
}
public string Operation(){
string s = component.Operation();s +=
"and listening to Classic FM"; return s;}
}
}
static
void Display(string s, IComponent c){
Console.WriteLine(s + c.Operation());}
static void Main(){
Console.WriteLine("Decorator Pattern\n"); IComponent component = new Component();Display(
"1. Basic component: ", component);Display(
"2. A-decorated : ", new DecoratorA(component));Display(
"3. B-decorated : ", new DecoratorB(component));Display(
"4. B-A-decorated : ", new DecoratorB(new DecoratorA(component))); DecoratorB b = new DecoratorB(new Component());Display(
"5. A-B-decorated : ", new DecoratorA(b)); Console.WriteLine("\t\t\t" + b.addedState + b.AddedBehavior());Display(
"6. A-B-decorated : ", new DecoratorA(new DecoratorB(component))); Console.ReadKey();}
But I just can't add those borders for the above 'Photo' example' using Decorator pattern. Hope I'm making some sense.
thanks
John
John,
Sorry if I seemed to be doubting your understanding, but it's a good place to start, and as it happens has given me a little more information.
Can the public void Drawer be likened to the public string Operation() in your second example, and in the language of your example, the Component implement the base drawing functionality, then the DecoratorA class then use the same graphics object to draw a border around the picture? The Comonent would have to be injected with the Bitmap, or path to it, so that the DecoratorA class has size information to draw the border? If the Component class is given the Bitmap, it can work out the size of the drawing area to use, the size of the photograph to draw the border around, and so on?
I hope that helps?
Martin Platt.
Martin,
This is what I came up with:
//**********************************************************
// Answer to decorator_pattern excercise 1
//**********************************************************
class
DecoratorPatternExcercise_1{
public interface IPhoto{
void Drawer(Object source, PaintEventArgs e);}
// The original Photo class public class Photo : Form, IPhoto{
Image image; public Photo(){
image =
new Bitmap("jug.jpg"); this.Text = "Lemonade"; this.Paint += new PaintEventHandler(Drawer);}
public void Drawer(Object source, PaintEventArgs e){
e.Graphics.DrawImage(image, 30, 20);
}
private void InitializeComponent(){
this.SuspendLayout(); // // Photo // this.ClientSize = new System.Drawing.Size(283, 250); this.Name = "Photo"; this.ResumeLayout(false);}
}
// This simple BorderedPhoto decorator adds a colored BorderedPhoto of fixed size class BorderedPhoto :Form, IPhoto{
IPhoto photo; Color color; public BorderedPhoto(IPhoto p, Color c){
photo = p;
color = c;
this.Paint += new PaintEventHandler(Drawer);}
public void Drawer(Object source, PaintEventArgs e){
photo.Drawer(source, e);
e.Graphics.DrawRectangle(
new Pen(color, 10), 25, 15, 215, 225);}
}
//// The TaggedPhoto decorator keeps track of the tag number which gives it //// a specific place to be written class TaggedPhoto : Form, IPhoto{
IPhoto photo; string tag; int number; static int count; List<string> tags = new List<string>(); public TaggedPhoto(IPhoto p, string t){
photo = p;
tag = t;
tags.Add(t);
number = ++count;
this.Paint += new PaintEventHandler(Drawer);}
public void Drawer(Object source, PaintEventArgs e){
photo.Drawer(source, e);
e.Graphics.DrawString(tag,
new Font("Arial", 16), new SolidBrush(Color.Black), new PointF(80, 100 + number * 20));}
public string ListTaggedPhotos(){
string s = "Tags are: "; foreach (string t in tags) s += t + " "; return s;}
}
static void Main(){
//// Application.Run acts as a simple client IPhoto photo; TaggedPhoto foodTaggedPhoto, colorTaggedPhoto, tag; BorderedPhoto composition; //// Compose a photo with two TaggedPhotos and a blue BorderedPhotophoto =
new Photo(); //Application.Run(photo);foodTaggedPhoto =
new TaggedPhoto(photo, "Food");colorTaggedPhoto =
new TaggedPhoto(foodTaggedPhoto, "Yellow");composition =
new BorderedPhoto(colorTaggedPhoto, Color.Blue); Application.Run(composition); //Console.WriteLine(colorTaggedPhoto.ListTaggedPhotos()); //// Compose a photo with one TaggedPhoto and a yellow BorderedPhotophoto =
new Photo();tag =
new TaggedPhoto(photo, "Jug");composition =
new BorderedPhoto(tag, Color.Yellow); Application.Run(composition); //Console.WriteLine(tag.ListTaggedPhotos());}
}
I don't know if that's the best practice, but it sure did solve the problem!! Thanks for your help.
John
John,
I can see something that doesn't gel between the two implementations, that's the derivation from a form class.
Using your first example to illustrate, I'd say that the form is implemented by 'Component' only, then the instance of the component is injected into the decorator classes. In that way you have only one instance of a form floating around, and you follow the pattern too.
Well done though, patterns aren't the easiest thing to get your head around in a real situation.
If you found my work helpful could you please mark MY post as helpful too?

Thanks,
Martin Platt.
- Wouldn't be better if you make explicit interface implementation like IPhoto.Drawer in Decorators and assign event to Drawer via interface instance:
this.Paint += new PaintEventHandler(photo.Drawer);
The example of Ms. Judith Bishop's book "C# 3.0 Design Pattern" starts the photo example on page16.
If you had continued to page 17 of the same book, the line "The first draws a blue border around the photo ... " displayed the code sample directly below the sentence.
Infact I'm reading the same book { Great highly recommended }.
I also located additional samples of design patterb code in C# at CodePlex via http://www.codeplex.com/patterns.
The other example you listed here was listed on page 14, has nothing to do with the photo image example.
I created a console app to implement the decorator pattern listed on page 14, something I would suggest doing and happy Ms. Bishop included for those who are 'hands-on' learners.
- BeMobile.
- I am working through this book as well at the moment, and the problem in the first original post is to load an actual file i.e.
new Bitmap("jug.jpg"); should beimage =
new Bitmap(@"C:\Users\Ira\Pictures\jug-lemonade.jpg");


