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 take
too much 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 many embedded pictures, Office does not
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 manufacturer's part in a database. It has a FullDescription property that
could be many pages of text. We do not 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.
Listing 22
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 sometext up.
if (_PartNumber == "1")
{
_PartText = "Pages of text for part1";
}
else if (_PartNumber == "2")
{
_PartText = "Pages of text for part2";
}
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.
Listing 23
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 = newPartDescription(_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 do not need to create the object as it has already
been done before. If we do not need the text after the call, we can set the
object to null after returning the text. This would be useful if we did not
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.
Listing 24
public string FullDescription
{
get
{
try
{
if (_PartDescription == null)
{
_PartDescription = newPartDescription(_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.