You need to operate on one or more objects but don't want to introduce special cases to your code. You designed an interface to operate on a single object but later discovered it needs to operate on a collection, and it's not easy to fix things. You want to to present a collection of objects as a single object to other classes.
Alternatively, you've written an object you don't want to or can't modify (for instance it's part of an external library) and you won't to inject some custom logic in certain cases. For example, you want to track usage statistics for a given method or you want to lazily instantiate a complex object.
Typically, the proxy class implements the same interface as the original object. In addition it usually adds a few methods for adding and removing objects from the proxy. When a third object attempts to call a method on the proxy the proxy simply iterates over each object and calls the corresponding method. Alternatively, it's possible that the proxy use the existing interface without modifications. In this case the proxy may be used to inject some additional behavior without modifying the original class' implementation.
public interface Animatable { public void render(Graphics g); public void update(); } public class AnimatableProxy implements Animatable { private LinkedList<Animatable> animatables; public void render(Graphics g) { for (Animatable a : animatables) { a.render(g); } } public void update() { for (Animatable a : animatables) { a.update(); } } public void add(Animatable a) { animatables.add(a); } }
Or without extending the interface
public interface Animatable { public void render(Graphics g); public void update(); } /* Measure the number of calls to render/update for a given animatable object. */ public class AnimatableProxy implements Animatable { private animatable:Animatable; public AnimatableProxy(Animatable base) { animatable = base; } public void render(Graphics g) { PerformanceCounter.increment("render"); animatable.render(g); } public void update() { PerformanceCounter.increment("update"); animatable.update(); } }
Adopting this pattern allows you to swap in a collection of objects in place of a single object without having to change the interface or behavior of the rest of your application. For that reason the proxy pattern is very common.
In the second example, adopting this interface allows you to extend the behavior of a class without actually modifying it. This is appropriate when working with an mature or external API. This may be desirable when the behavior you wish to add is somehow intended for a special or limited purpose. Good candidates are performance/code coverage measurement and lazy loading/creation of complex objects/resources.
This pattern obviously adds overhead to your application by introducing a new object which exists solely to pass commands around. In addition, applying this pattern isn't straightforward for some interfaces. For example, when an object is meant to return something it isn't immediately clear how the proxy should route the output of its members.