Design Patterns - Structural Patterns - Proxy
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.