Proxy Pattern
In my last post I wrote about structural patterns and introduced the decorator pattern.
In this post I'll introduce one of the most useful structural patterns - the proxy pattern.
What is the Proxy Pattern?
The proxy pattern is all about the making of small public objects that create and access complex objects.
The proxy object is the gateway to the complex object and it communicate (send requests) with that object.
One other reason to create a proxy is to hand the creation of an object to the proxy if that object is expensive to create.
For a UML diagram of the pattern go to dofactory site.
There are several kind of proxies for example remote proxies (WCF service reference, Web Services web reference, Remoting references etc)
or authentication proxies (logging control is a proxy for a logging system).
Real Life Proxy Example
My favorite example for the use of proxies is the Policy Injection Application Block.
The PIAB provides a factory (another pattern that I'll write about in the future) for creating or wrapping policy-enabled objects.
A policy in PIAB is the combination of a series of handlers that execute when client code calls methods of the class.
When defining policies for objects, a proxy object is returned instead of the real object.
Making a request to the proxy object execute a handler pipeline before and after the real object is called.
Each handler can add or change the request to the real object.
A diagram that is taken from the enterprise library documentation shows the behavior of PIAB:
For more details about PIAB go to Patterns & Practices site or open the enterprise library documentation.
The PIAB is an example for a kind of proxies that is called smart proxies.
Example in C#
Lets look at a proxy example:
In the example we have 4 players -
Book object that represent a data object.
ILibrary that represent an interface for borrowing and returning books.
BookLibrary that represent a book library which implement the ILibrary interface.
LibraryProxy that represent the proxy for the BookLibrary class.
public class Book
{
#region Members
private string _strBookName;
private string _strBookISBN;
#endregion
#region Properties
public string BookName
{
get { return _strBookName; }
set { _strBookName = value; }
}
public string BookISBN
{
get { return _strBookISBN; }
set { _strBookISBN = value; }
}
#endregion
#region Ctor
public Book(string bookName, string bookISBN)
{
BookName = bookName;
BookISBN = bookISBN;
}
#endregion
}
public interface ILibrary
{
void BorrowBook(Book book);
void ReturnBook(Book book);
}
public class BookLibrary : ILibrary
{
#region ILibrary Members
public void BorrowBook(Book book)
{
Console.WriteLine("Borrow the book: {0} with the ISBN: {1}", book.BookName, book.BookISBN);
}
public void ReturnBook(Book book)
{
Console.WriteLine("Return the book: {0} with the ISBN: {1}", book.BookName, book.BookISBN);
}
#endregion
}
public class LibraryProxy : ILibrary
{
#region Members
private BookLibrary _library;
#endregion
#region Ctor
public LibraryProxy()
{
_library = new BookLibrary();
}
#endregion
#region ILibrary Members
public void BorrowBook(Book book)
{
_library.BorrowBook(book);
}
public void ReturnBook(Book book)
{
_library.ReturnBook(book);
}
#endregion
}
Summary
To sum up this post, the proxy pattern should be used in these situations:
1. You need to access a remote object.
2. You have an object that its creation is expensive.
3. You need to perform an action when an object is called.
In the next post I'll continue the tour in the design patterns world.
Structural Patterns And Decorator Pattern
Structural Patterns
In this lesson, I'm going to write about the first of the three design pattern groups - the structural patterns.
As I wrote in my first post about design patterns, the structural patterns deal with composition of classes and objects and enable us to form larger structures.
The structural patterns include: Adapter, Bridge, Composite, Decorator, Facade, Flyweight and Proxy.
The advantage of using these patterns is that you can apply them while you are designing your project, or later on when you deploy or in the faze of maintenance.
Decorator Pattern
I'm going to start with the decorator pattern because I'm using it a lot these days and it is a common pattern.
The decorator pattern or wrapper (depends on your project architect) is providing a way to add functionality or new state to an implemented object without touching that object.
The decorator has two types of relations with the object it decorates.
The decorator is an object of the type it decorates therefore it can be used in the places that the original decorated object was used.
The decorator has an object of the type it decorates (one or more instance of that type) inside of it therefore it can use the functionality of that object.
For a UML diagram of the pattern go to dofactory site.
In the .Net framework there are a lot of wrappers and you can find some examples in the System.IO namespace.
Can you guess which classes are decorators? A tip - look at the Stream class and StreamWriter and StreamReader classes for example.
Decorator C# Example
Lets look at a little decorator example :
We have two players in the example - the Cop class and the Detective class.
The Cop class is the decorated class and the detective class is the decorator.
The Cop class:
public class Cop
{
#region Members
private string _Name;
#endregion
#region Properties
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}
#endregion
#region Ctor
public Cop(string name)
{
Name = name;
}
#endregion
#region Methods
public virtual void arrestSuspect()
{
Console.WriteLine("Arrest suspect");
}
public virtual void detainSuspect()
{
Console.WriteLine("Detain suspect");
}
#endregion
}
As you can see there is nothing interesting about the Cop class. It has a Name property and two methods detainSuspect and arrestSuspect.
Now lets look on the Detective class:
public class Detective : Cop
{
#region Members
private Cop _cop;
#endregion
#region Ctor
public Detective(Cop cop)
{
_cop = cop;
}
#endregion
#region Methods
public void investigateSuspect()
{
Console.WriteLine("{0} Investigates the Suspect", Name);
}
public override void detainSuspect()
{
Console.WriteLine("Detain suspect and investigate");
}
#endregion
}
The Detective class wraps the Cop class by having a Cop member inside and therefore can use it's functionality.
Also, the Detective class inherits from the Cop class and therefore we can use it whenever we can use the Cop class.
You can see that the Detective class adds functionality that wasn't present in the Cop class - investigateSuspect method.
Summary
To sum up the post, the decorator pattern is useful and is implemented widely in .Net framework mainly in System.IO.
In my current project we use the decorator pattern to wrap legacy objects and to add them new functionality.
In the next post I'll continue the tour in the design patterns world and the structural patterns.
Prolog - the book
Did you ever wonder what makes a good solution?
Did you ever thought why solutions sometime fall apart?
Somebody asked me once why do I think that my solution to a problem is good.
To tell you the truth, Only time will tell if the solution was good or not.
The only thing that I can be sure about is that I try to simplify my solutions and I'm using a lot of design patterns on the way.
I was first introduced to design patterns in a J2EE elective course when I was a computer science student.
The lecturer introduced us to the "bible" of design patterns - Design Patterns: Elements of Reusable Object-Oriented Software.
I remember hearing other students saying things like "I'm not going to bother myself in reading that book. this is only an elective course.".
Puzzled about design patterns, I went and bought the book and it changed my point of view about programing forever.
I often find myself, even in these days, reading chapters from that book and the book is placed in my home library.
So, what are design patterns?
From Wikipedia - "a design pattern is a general reusable solution to a commonly occurring problem in software design.
A design pattern is not a finished design that can be transformed directly into code.
It is a description or template for how to solve a problem that can be used in many different situations."
The patterns are divided to three groups by their purpose - structural patterns, creational patterns and behavioral patterns.
The structural patterns deal with composition of classes and objects to form larger structures.
The creational patterns deal with the process of object creation.
The behavioral patterns deal with classes or object interaction and algorithms.
In the next post series I'm going to drill down into some common design patterns that I'm using often including implementation in C# and use cases.
The book details on amazon:
Design Patterns: Elements of Reusable Object-Oriented Software
(Addison-Wesley Professional Computing Series)
ISBN: 0201633612
ISBN-13: 9780201633610
"שעת לילה מאוחרת
אגלי זיעה מכסים את מצחו
תקתוק מקשים בלתי פוסק ברקע
יבבת תינוק נשמעת מכיוון הרחוב שבו הוא מתגורר ומיד אחריה קולו החלוש של ההורה שהתעורר לבדוק מה קרה
מחשבות טורדות את מוחו בעת שהוא חושב מה הוא עומד לפרסם בפוסט הראשון שלו
לבסוף עוד שורות נוספות לפוסט והוא מתחיל לנשום לרווחה..."
שמי גיל פינק ואני עוד "ילד חדש" בשכונה הותיקה של הבלוגים.
אני מועסק בחברת SRL Group כתוכניתן בכיר בתחום פיתוח ותשתיות NET. וכיועץ בעיקר בנושאים של תשתיות.
מטרת הבלוג הזה היא להעביר מהידע והניסיון שאותו צברתי במרוצת השנים בכל הקשור בפיתוח.