Level: Beginner + to Object Oriented Programming; Beginner + with .NET and C# The Proxy design pattern shows a way to do just in time loading of objects that would consume too much memory to keep around, or takes a lot of time to load. This can be a very useful pattern for many applications. A good example of this pattern is in Microsoft Office. When you open a large Word document that has lots of embedded pictures, Office doesn’t load them all at the time you open the document. As you scroll down, Office will pull the pictures from the disk file and insert them into the document. You can see this by scrolling very fast down the document. It takes a second or so for the document to “catch up” to you and show the visible images.
For our example, we will have a part object that represents a manufacturers part in a database. It has a FullDescription property that could be many pages of text. We don’t want to load this text unless the user really wants to see it.
We first start by creating a wrapper for the description. It is a very simple object that just exposes the text we want to return. In a real world application the text would come from a database or something similar.
Code:
using System;
namespace ProxyDesignPattern
{
public class PartDescription
{
private string _PartNumber;
private string _PartText;
public PartDescription(string PartNumber)
{
_PartNumber = PartNumber;
//load text now For the demo, we just make some text up.
if(_PartNumber == "1")
{
_PartText = "Pages of text for part 1";
}
else if(_PartNumber == "2")
{
_PartText = "Pages of text for part 2";
}
else
{
_PartText = "Part Not Found";
}
}
public string ReturnText
{
get{return _PartText;}
}
}
}
The Part class is also simple. It just allows entry of the part number and then has a method to return the part text.
Code:
using System;
namespace ProxyDesignPattern
{
public class Part
{
private string _PartNumber;
private PartDescription _PartDescription;
public Part()
{
_PartDescription = null;
}
public string PartNumber
{
get{return _PartNumber;}
set{_PartNumber = value;}
}
public string FullDescription
{
get
{
if(_PartDescription == null)
{_PartDescription = new PartDescription(_PartNumber);}
return _PartDescription.ReturnText;
}
}
}
}
The interesting method is FullDescription. You will see that the get method first checks to see if the _PartDescription object is null or not. If not, then we don’t need to create the object as it has already been done before. If we don’t need the text after the call, we can set the object to null after returning the text. This would be useful if we didn’t want to keep the overhead of the part text around. After passing the text to some other program, we can clear it in our object. Here is the rewrite of the function.
Code:
public string FullDescription
{
get
{
try
{
if(_PartDescription == null)
{_PartDescription = new PartDescription(_PartNumber);}
return _PartDescription.ReturnText;
}
catch
{return "Error";}
finally
{_PartDescription = null;}
}
}
We have added error handling in this function to allow for a finally block to null the object.
The proxy pattern comes in four flavors.
- Remote Proxy
- Virtual Proxy
- Protection Proxy
- Smart Reference
The above code is an example of a Virtual Proxy. Virtual Proxy object create expensive objects on demand.[GOF208]
A remote proxy provides a local representative for an object in a different address space.[GOF208] This proxy is used to send requests to remote object and any data the remote object needs.
A protection proxy controls access to the original object.[GOF208] This proxy is used to control access to an object based on some kind of client permissions.
A smart reference is a replacement for a bare pointer that performs additional actions when an object is referenced.[GOF209] This patterns isn't used as much with .Net as there are very few uses for pointers anymore. One use for the smart reference could be in multithreading. The reference could make sure the object is locked for writing.
John Spano
President
NeoTekSystems, Inc.
www.NeoTekSystems.com
Microsoft MVP, MCSD, MCTS-Windows, MCTS-Web, MCPD-Distributed, MCITP-SQLDev, MCITP-SQLAdmin