CHAPTER 6
Proxy Pattern
This chapter covers the Proxy pattern.
GoF Definition
Provide a surrogate or placeholder for another object to control access to it.
Concept
A proxy is basically a substitute for an intended object. When a client deals with a proxy
object, it thinks that it is dealing with the actual object. You need to support this kind of
design because dealing with an original object is not always possible. This is because of
many factors such as security issues, for example. So, in this pattern, you may want to
use a class that can perform as an interface to something else.
Real-Life Example
In a classroom, when one student is absent, his best friend may try to mimic his voice
during roll call to try to get the teacher to think his friend is there.
Computer World Example
An ATM implementation will hold proxy objects for bank information that exists on a
remote server. In the real programming world, creating multiple instances of a complex
object (a heavy object) is costly in general. So, whenever you can, you should create
multiple proxy objects that can point to the original object. This mechanism can also
help you to save the computer/system memory.
71
© Vaskaran Sarcar 2018
V. Sarcar, Design Patterns in C#, [Link]
Chapter 6 Proxy Pattern
Illustration
In this program, you are calling the DoSomeWork() method of the proxy object that, in
turn, calls the DoSomeWork() method of an object of ConcreteSubject. When customers
see the output, they think they have invoked the method from their intended object
directly.
Class Diagram
Figure 6-1 shows the class diagram.
Figure 6-1. Class diagram
72
Chapter 6 Proxy Pattern
Directed Graph Document
Figure 6-2 shows the directed graph document.
Figure 6-2. Directed Graph Document
Solution Explorer View
Figure 6-3 shows the high-level structure of the parts of the program. (Note that you
could separate the proxy class into a different file. But since the parts are small in this
example, I have put everything in a single file.)
73
Chapter 6 Proxy Pattern
Figure 6-3. Solution Explorer View
Implementation
Here’s the implementation:
using System;
namespace ProxyPattern
{
/// <summary>
/// Abstract class Subject
/// </summary>
public abstract class Subject
{
74
Chapter 6 Proxy Pattern
public abstract void DoSomeWork();
}
/// <summary>
/// ConcreteSubject class
/// </summary>
public class ConcreteSubject : Subject
{
public override void DoSomeWork()
{
[Link]("[Link]()");
}
}
/// <summary>
/// Proxy class
/// </summary>
public class Proxy : Subject
{
Subject cs;
public override void DoSomeWork()
{
[Link]("Proxy call happening now...");
//Lazy initialization:We'll not instantiate until the method is
//called
if (cs == null)
{
cs = new ConcreteSubject();
}
[Link]();
}
}
class Program
{
static void Main(string[] args)
{
75
Chapter 6 Proxy Pattern
[Link]("***Proxy Pattern Demo***\n");
Proxy px = new Proxy();
[Link]();
[Link]();
}
}
}
Output
Here’s the output:
***Proxy Pattern Demo***
Proxy call happening now...
[Link]()
Q&A Session
1. What are the different types of proxies?
Answer:
These are the common types of proxies:
• Remote proxies: These proxies can hide an object that stays in a
different address space.
• Virtual proxies: These proxies are used to perform optimization
techniques such as creating a heavy object on an on-demand
basis.
• Protection proxies: These proxies generally deal with different
access rights.
• Smart reference: This can perform some additional housekeeping
when an object is accessed by a client. A typical operation may
include counting the number of references to an object at a
particular moment.
76
Chapter 6 Proxy Pattern
2. You could create the ConcreteSubject instance in the proxy
class constructor as shown here:
/// <summary>
/// Proxy class
/// </summary>
public class Proxy : Subject
{
Subject cs;
public Proxy()
{
//Instantiating inside the constructor
cs = new ConcreteSubject();
}
public override void DoSomeWork()
{
[Link]("Proxy call happening now..");
[Link]();
}
}
Is this understanding correct?
Answer:
Yes, you could do that. But if you follow this design, whenever you
instantiate a proxy object, you would need to instantiate an object
of the ConcreteSubject class also. So, this process may end up
creating unnecessary objects.
3. But with this lazy instantiation process, you may create
unnecessary objects in a multithreaded application. Is this
understanding correct?
Answer:
Yes. In this book, I am presenting simple illustrations only, so I
have ignored that part. In the discussions of the Singleton pattern
in Chapter 1, you analyzed some alternative approaches for
77
Chapter 6 Proxy Pattern
dealing with multithreaded environments. You can always refer
to those discussions in situations like this. (For example, in this
particular scenario, you could implement a smart proxy to ensure
that a particular object is locked before you grant access to the
object.)
4. Can you give an example of a remote proxy?
Answer:
Suppose you want to call a method of an object but the object is
running in a different address space (for example, in a different
location or on a different computer). How can you proceed? With
the help of remote proxies, you can call the method on the proxy
object, which in turn will forward the call to the actual object
that is running on the remote machine. This type of need can be
realized through different well-known mechanisms such as ASP.
NET, CORBA, or Java’s RMI. In C# applications, you can exercise
a similar mechanism with WCF (.NET Framework version 3.0
onward) or .NET web services/remoting (mainly used in earlier
versions).
Figure 6-4 shows a simple remote proxy structure.
Figure 6-4. A simple remote proxy diagram
78
Chapter 6 Proxy Pattern
5. When can you use a virtual proxy?
Answer:
You can use virtual proxies to avoid loading an extremely large
image multiple times.
6. When can you use a protection proxy?
Answer:
In an organization, the security team can implement a protection
proxy to block Internet access to specific web sites.
Consider the following example, which is basically a modified
version of the Proxy pattern implementation described earlier.
For simplicity, let’s assume you have only three registered users
who can exercise the proxy method DoSomeWork(). If any other
user (say Robin) tries to invoke the method, the system will reject
those attempts. When the system rejects this kind of unwanted
access, there is no point in making a proxy object. So, if you avoid
instantiating an object of ConcreteSubject in the proxy class
constructor, you can easily avoid creating objects unnecessarily.
Now let’s go through the modified implementation.
Modified Implementation
Here’s the modified implementation:
using System;
using [Link];//For Contains() method below
namespace ProxyPatternQAs
{
/// <summary>
/// Abstract class Subject
/// </summary>
public abstract class Subject
{
79
Chapter 6 Proxy Pattern
public abstract void DoSomeWork();
}
/// <summary>
/// ConcreteSubject class
/// </summary>
public class ConcreteSubject : Subject
{
public override void DoSomeWork()
{
[Link]("[Link]()");
}
}
/// <summary>
/// Proxy class
/// </summary>
public class Proxy : Subject
{
Subject cs;
string[] registeredUsers;
string currentUser;
public Proxy(string currentUser)
{
//Avoiding to instantiate inside the constructor
//cs = new ConcreteSubject();
//Registered users
registeredUsers =new string[]{"Admin","Rohit","Sam"};
[Link] = currentUser;
}
public override void DoSomeWork()
{
[Link]("\nProxy call happening now...");
[Link]("{0} wants to invoke a proxy
method.",currentUser);
if ([Link](currentUser))
{
80
Chapter 6 Proxy Pattern
//Lazy initialization: We'll not instantiate until the
method is called
if (cs == null)
{
cs = new ConcreteSubject();
}
[Link]();
}
else
{
[Link]("Sorry {0}, you do not have access.",
currentUser);
}
}
}
class Program
{
static void Main(string[] args)
{
[Link]("***Proxy Pattern Demo***\n");
//Authorized user-Admin
Proxy px1 = new Proxy("Admin");
[Link]();
//Unwanted User-Robin
Proxy px2 = new Proxy("Robin");
[Link]();
[Link]();
}
}
}
81
Chapter 6 Proxy Pattern
Modified Output
Here’s the modified output:
***Proxy Pattern Demo***
Proxy call happening now...
Admin wants to invoke a proxy method.
[Link]()
Proxy call happening now...
Robin wants to invoke a proxy method.
Sorry Robin, you do not have access.
7. It looks like proxies act like decorators. Is this understanding
correct?
Answer:
A protection proxy might be implemented like a decorator, but you should
not forget the intent of a proxy. Decorators focus on adding responsibilities,
but proxies focus on controlling the access to an object. Proxies differ
from each other through their types and implementations. So, if you
can remember their purposes, in most cases you will be able to clearly
distinguish proxies from decorators.
82