Proxy

Introduction

When you want to use a large object in memory, a file or some other resource that is impossible or expensive to duplicate, but you do not want to instantiate it or copy it right now cause you only need a portion information of it, you can use Proxy pattern. A proxy supplies an interface for you to do most operation of the original one, the proxy will forward them to the original object. Proxy is well known in reference counting pointer object.

Definition

Provide a supporgate or placeholder for another object to control access to it.

UML class diagram

Proxy pattern

Participants

  • Proxy
    • maintains a reference that lets the proxy access the real subject. Proxy may refer to a Subject if the RealSubject and Subject interfaces are the same.
    • provides an interface identical to Subject’s so that a proxy can be substituted for the real object.
    • control access to real subject and may be responsible for creating and deleting it.
    • other responsibilities depend on the kind of proxy:
      • remote proxies are responsible for encoding a request and its arguments and for sending the encoded request to the real subject in a different address space.
      • virtual proxies may cache additional information about the real subject so that they can postpone accessing it.
      • protection proxies check that the call has the access permissions required to perform a request.
  • Subject
    • defines the interface for the RealSubject and Proxy so that a Proxy can be used anywhere a RealSubject is expected.
  • RealSubject
    • defines the real object that the proxy represents.

Example

// Subject
public interface Image {
	public void draw();
}

//Proxy
public class ImageProxy implements Image {
	
	private Image realImage = null;
	
	private String fileName = null;
	
	public ImageProxy(String fileName) {
		this.fileName = fileName;
	}

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		if (realImage == null) {
			realImage = new RealImage(fileName);
		}
		realImage.draw();
	}

}

// RealSubject
public class RealImage implements Image {

	private String fileName;

	public RealImage(final String fileName) {
		this.fileName = fileName;
		loadImage();
	}

	private void loadImage() {
		System.out.println("loading image:" + fileName + " from disk...");
	}

	@Override
	public void draw() {
		// TODO Auto-generated method stub
		System.out.println("drawing image:" + fileName);
	}

}

// Client
class Client {
	private final Image img1;
	private final Image img2;

	public Client() {
		img1 = new ImageProxy("Test_Image_1.PNG");
		img2 = new ImageProxy("Test_Image_2.PNG");
	}

	public void show() {
		img1.draw();	// need load

		img2.draw();	// need load

		img1.draw();	// do not need load

		img2.draw();	// do not need load
	}
}

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new Client().show();
	}

}

Output:

loading image:Test_Image_1.PNG from disk...
drawing image:Test_Image_1.PNG
loading image:Test_Image_2.PNG from disk...
drawing image:Test_Image_2.PNG
drawing image:Test_Image_1.PNG
drawing image:Test_Image_2.PNG

Well, it looks like Adapter pattern, an adapter provides a different interface to the object it adapts. In contrast, a proxy provides the same interface as its subject.

Decorators may have similar implementations as proxies, but decorators have a different purpose: to add one or more responsibilities to an object, whereas proxies controls the accessibilities.

Usage

  • When you need a more versatile or sophisticated reference to an object than a simple pointer.

See Also

blog comments powered by Disqus