Design Pattern - Structural - Proxy Pattern

introduce

Intent : Provide a stand-in or placeholder for another object to control access to this object.

The main solution : the problem caused by directly accessing the object, for example: the object to be accessed is on a remote machine. In object-oriented systems, for some reasons (such as object creation is expensive, or some operations require security control, or require out-of-process access), direct access will bring a lot of trouble to users or system structures. We can add an access layer to this object when accessing this object.

When to use : Want to do some control when accessing a class.

How to fix : Add middle layers.

Key code : implementation and proxy class combination.

proxy1.png

accomplish

A mock loading image implementation class

Basic implementation

public interface Image {
	void display();
}

proxied class

public class RealImage implements Image {

	private String fileName;

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

	[@Override](https://my.oschina.net/u/1162528)
	public void display() {
		System.out.println("Displaying " + fileName);
		
		try {
			Thread.sleep(666);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
	}

}

Proxy class - used to calculate the time spent by diplay()

public class ProxyImage implements Image {

	private RealImage realImage;
	private String fileName;

	public ProxyImage(String fileName) {
		this.fileName = fileName;
	}

	[@Override](https://my.oschina.net/u/1162528)
	public void display() {
		
		long begin = System.currentTimeMillis();
		
		if (realImage == null) {
			realImage = new RealImage(fileName);
		}
		
		realImage.display();
		
		long end = System.currentTimeMillis();
		
		System.out.println("It's spent " + (end - begin)+ "ms");
		
	}
}

run class

public class ProxyPatternDemo {

	public static void main(String[] args) {
		Image image = new ProxyImage("18stop.jpg");

		image.display();
	}
}

operation result

Displaying 18stop.jpg
It's spent 670ms

JDK dynamic proxy

proxy2.png

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import designpattern.proxy.example1.Image;
import designpattern.proxy.example1.RealImage;

public class TimerHandler implements InvocationHandler {

	private Object target;
	
	public TimerHandler(Object target) {
		this.target = target;
	}
	
	[@Override](https://my.oschina.net/u/1162528)
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		long begin = System.currentTimeMillis();
		
		Object obj = method.invoke(target, args);
		
		long end = System.currentTimeMillis();
		System.out.println("It's spent " + (end - begin)+ "ms");
		
		return obj;
	}
	
	public static void main(String[] args) {
		RealImage image = new RealImage("18stop.jpg");
		
		TimerHandler timer = new TimerHandler(image);
		
		Image proxyImage = (Image)Proxy.newProxyInstance(
				image.getClass().getClassLoader(), 
				image.getClass().getInterfaces(), 
				timer);
		
		proxyImage.display();
		
	}

}

operation result

Displaying 18stop.jpg
It's spent 675ms

References and citations

1. "Head First Design Patterns" Eric Freeman et al

2. Proxy Mode | Rookie Tutorial

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324376636&siteId=291194637