Design Patterns Uncovered: The Proxy Pattern

Today's pattern is the Proxy pattern, another simple but effective pattern that helps with controlling use and access of resources. 

Proxy in the Real World 

A Proxy can also be defined as a surrogate. In the real work a cheque or credit card is a proxy for what is in our bank account.  It can be used in place of cash, which is what is needed, and provides a means of accessing that cash when required. And that's exactly what the Proxy pattern does - controls and manage access to the object they are "protecting".

The Proxy Pattern

The Proxy is known as a  structural  pattern, as it's used to form large object structures across many disparate objects. The definition of Proxy provided in the original Gang of Four book on Design Patterns states: 

Allows for object level access control by acting as a pass through entity or a placeholder object. 

 
So it's quite a simple concept - to save on the amount of memory used, you might use a Proxy. Similarly, if you want to control access to an object, the pattern becomes useful.

Let's take a look at the diagram definition before we go into more detail.

As usual, when dealing with design patterns we code to interfaces. In this case, the interface that the client knows about is theSubject. Both the Proxy and RealSubject objects implement the Subject interface, but the client may not be able to access the RealSubject without going through the Proxy. It's quite common that the Proxy would handle the creation of the RealSubjectobject, but it will at least have a reference to it so that it can pass messages along.

Let's take a look at this in action with a sequence diagram. 

 As you can see it's quite simple - the Proxy is providing a barrier between the client and the real implementation.

There are many different flavours of Proxy, depending on it's purpose. You may have a protection proxy, to control access rights to an object. A virtual proxy handles the case where an object might be expensive to create, and a remote proxy controls access to a remote object. 

You'll have noticed that this is very similar to the Adapter pattern. However, the main difference between bot is that the adapter will expose a different interface to allow interoperability. The Proxy exposes the same interface, but gets in the way to save processing time or memory.

Would I Use This Pattern?

This pattern is recommended when either of the following scenarios occur in your application:

  • The object being represented is external to the system.
  • Objects need to be created on demand. 
  • Access control for the original object is required
  • Added functionality is required when an object is accessed.

Typically, you'll want to use a proxy when communication with a third party is an expensive operation, perhaps over a network. The proxy would allow you to hold your data until you are ready to commit, and can limit the amount of times that the communication is called.

The proxy is also useful if you want to decouple actual implementation code from the access to a particular library. Proxy is also useful for access to large files, or graphics. By using a proxy, you can delay loading the resource until you really need the data inside. Without the concept of proxies, an application could be slow, and appear non-responsive. 

So How Does It Work In Java?

Let's continue with the idea of using a proxy for loading images. First, we should create a common interface for the real and proxy implementations to use:

1. public interface Image
2. {
3. public void displayImage();
4. }

The RealImage implementation of this interface works as you'd expect:

01. public class RealImage implements Image
02. {
03.  
04. public RealImage(URL url)
05. {
06. //load up the image
07. loadImage(url);
08. }
09.  
10. public void displayImage()
11. {
12. //display the image
13. }
14.  
15. //a method that only the real image has
16. private void loadImage(URL url)
17. {
18. //do resource intensive operation to load image
19. }
20.  
21.  
22. }

Now the Proxy implementation can be written, which provides access to the RealImage class. Note that it's only when we call the displayImage() method that it actually uses the RealImage. Until then, we don't need the data.

01. public class ProxyImage implements Image
02. {
03. private URL url;
04.  
05. public ProxyImage(URL url)
06. {
07. this.url = url;
08. }
09.  
10. //this method delegates to the real image
11. public void displayImage()
12. {
13. RealImage real = new RealImage(url);
14. real.displayImage();
15. }
16.  
17. }

And it's really as simple as that. As far as the client is concerned, they will just deal with the interface. 

Watch Out for the Downsides

Usually this is the stage that I point out the disadvantages to the pattern. Proxy is quite simple, and pragmatic, and it's one pattern that I can't think of any downsides for. Perhaps you know of some? If so, please share them in the comments section.

Next Up

The Decorator pattern is a close relation to the Proxy pattern, so we'll take a look at that next week. 

Comments

Josh Marotti replied on Fri, 2010/03/12 - 6:41am

While you gave a simple example, a more complex example would be to use, say, an aspect as a proxy.  The downside here is 'magic' could be happening that an extender is unaware of (a 'black-box' problem).

Peter Veentjer replied on Fri, 2010/03/12 - 8:06am

There are 2 big problems with proxies, especially in enterprise environments.

 

1) You can't do self calls. A good example is a proxy that does transactionmanagement or security. So you need to make sure that instead of doing a self call, you forward the call to the proxy. This makes simple classes complex.

2) There are issues with identity; a good examlpe is a hibernate proxy which makes it impossible to do a reference comparison, even though you get the guarantee that there are not multiple object instances of the same entity in a session. 

So although a proxy is a nice design pattern in theory, it often sucks in practice.

 

Peter Veentjer

Multiverse Software Transactional Memory for Java

http://multiverse.codehaus.org

Neil Bartlett replied on Fri, 2010/03/12 - 7:09am

Since you asked, I can think of a couple of downsides -- though of course the pattern is still valuable.

First, a proxy can mask the lifecycle and state of a volatile resource from its client. A client may call the proxy not realising that the resource is currently unavailable... in this case the proxy has to either block until a resource is available again, or it must produce some kind of error. In Java terms it would have to be an unchecked exception, since the Proxy must comply with the interface of the original object. Also the client may not be aware that the resource it is calling now is not the same resource it called a second ago; if there is any state on the resource then the client may be confused that the state appears to have been forgotten.

Second, if a proxy is used to represent a remote resource in the local process, this can disguise the fact that remote communication is involved. As we know, remote invocation is completely different from local invocation, and our programs should not treat it as if it were the same. It is better if the proxy declares somehow that it is a proxy for a remote resource, rather than a local resource. Then clients would have be able to choose only local resources, or to modify their behaviour when using a remote resource.

James Sugrue replied on Fri, 2010/03/12 - 7:57am

Thanks for the downsides guys - keep them coming :)

Bogdan Marian replied on Mon, 2010/03/15 - 7:54am

By looking at the comments above, it looks like Proxy is a nasty design pattern.

But don't forget it is (was) used by Hibernate for implementing lazy loading...

Proxy can also be used for implementing AOP...

Allen Geer replied on Tue, 2010/03/23 - 8:57pm

I have found that using the proxy pattern, as implemented and defined in the Java specs, is a great solution for applications that have low load. But the computing time incurred with all the reflection calls nessecary to implement this pattern can slow an application down quite a bit. While elegant from a design prospective, the cost in terms of computational time can be somewhat limiting for high load situations.

Reza Ghafari replied on Tue, 2010/03/23 - 11:00pm

To me, the link between Proxy and RealSubject should be "optional" as we do not want to forward requests to the RealSubject in all the cases.

Mahesh Kulkarni replied on Thu, 2010/05/13 - 1:58am

Good Article... worth reading...

Sunny Gupta replied on Thu, 2013/08/15 - 1:14pm in response to: Neil Bartlett

 Hi Neil, 

As you told that "the client may not be aware that the resource it is calling now is not the same resource it called a second ago", Did you refer the resource as actual resource or the proxy resource? Would you please elaborate

Also when you write "if there is any state on the resource then the client may be confused that the state appears to have been forgotten". Would you please explain this comment by some example.

Thanks,

Sunny

Jeet Jain replied on Fri, 2013/08/16 - 12:26am in response to: Peter Veentjer

 Hi Peter,


I have few questions to you:

1) What is the meaning of self call

2) Why we can not do a reference comparison when both refers to proxy object

Manoj Kumar replied on Thu, 2013/09/26 - 11:18am

  Proxy Design Pattern in Java, lazy loading using Proxy Design Pattern

What is Proxy Design Pattern 

1. Proxy design patten works on the principal of exposing an Java Instance through a proxy instead of actual object. 

2. Client would never know anything about actual object and through Proxy only relevant behavior of actual object will be exposed to client.

3. Proxy Pattern can be used for applying security on actual Object. Service provider does not want actual class to be visible to any client Instead It would be shared as per Client contract agreement . Service provider may agree to share only a part of Service with it's client and for that It may expose a different contract in the form of interface in java . 


4. This concept is very useful for lazily loading an instance . Data will be loaded only when it is actually required in an operation . 

Learn more about proxy design pattern here  -- <a href="http://efectivejava.blogspot.in/2013/09/proxy-design-pattern-in-java-lazy.html?utm_source=BP_recent">Proxy Design Pattern</a>

http://efectivejava.blogspot.in/2013/09/proxy-design-pattern-in-java-lazy.html?utm_source=BP_recent

Reference: http://java.dzone.com/articles/design-patterns-proxy

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值