1. 程式人生 > >Java設計模式之十二(代理模式)

Java設計模式之十二(代理模式)

一、什麼是代理模式

Proxy模式又叫做代理模式,是構造型的設計模式之一,它可以為其他物件提供一種代理(Proxy)以控制對這個物件的訪問。

所謂代理,是指具有與代理元(被代理的物件)具有相同的介面的類,客戶端必須通過代理與被代理的目標類互動,而代理一般在互動的過程中(互動前後),進行某些特別的處理。

二、代理模式的結構

三、代理模式的角色和職責

subject(抽象主題角色):真實主題與代理主題的共同介面。

RealSubject(真實主題角色): 定義了代理角色所代表的真實物件。

Proxy(代理主題角色):     含有對真實主題角色的引用,代理角色通常在將客戶端呼叫傳遞給真是主題物件之前或者之後執行某些操作,而不是單純返回真實的物件。

四、動態代理

1. InvocationHandler 介面


2. invoke方法


3. Proxy.newProxyInstance();

程式碼實現

1、代理模式

抽象角色類:

package com.qianyan.proxy;

public interface Subject {

	//賣書
	public void sailBook();
}

真實角色類:

package com.qianyan.proxy;

public class RealSubject implements Subject{

	public void sailBook() {
		System.out.println("賣書");
	}

}

代理物件類:
package com.qianyan.proxy;

public class ProxySubject implements Subject{

	private RealSubject realSubject;

	public RealSubject getRealSubject() {
		return realSubject;
	}

	public void setRealSubject(RealSubject realSubject) {
		this.realSubject = realSubject;
	}
	
	//賣書
	public void sailBook() {
		dazhe();
		realSubject.sailBook();
		give();
	}
	
	//打折
	public void dazhe() {
		System.out.println("打折");
	}
	
	//贈送代金券
	public void give() {
		System.out.println("贈送代金券");
	}
}
測試類:
package com.qianyan.proxy;

public class MainClass {

	public static void main(String[] args) {
		RealSubject realSubject = new RealSubject();
		ProxySubject proxy = new ProxySubject();
		proxy.setRealSubject(realSubject);
		
		proxy.sailBook();
	}
}


2、動態代理:

抽象角色類

package com.qianyan.dynamicproxy;

public interface Subject {

	//賣書
	public void sailBook();
}

真實角色類:
package com.qianyan.dynamicproxy;

public class RealSubject implements Subject {

	public void sailBook() {
		System.out.println("賣書");
	}
	
}

Handler類:
package com.qianyan.dynamicproxy;

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

public class MyHandler implements InvocationHandler {

	private RealSubject realSubject;
	
	public RealSubject getRealSubject() {
		return realSubject;
	}

	public void setRealSubject(RealSubject realSubject) {
		this.realSubject = realSubject;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result = null;
		dazhe();
		result = method.invoke(realSubject, args);
		give();
		return result;
	}
	
	//打折
	public void dazhe() {
		System.out.println("打折");
	}
	
	//贈送代金券
	public void give() {
		System.out.println("贈送代金券");
	}

}

測試類:
package com.qianyan.dynamicproxy;

import java.lang.reflect.Proxy;

public class MainClass {

	public static void main(String[] args) {
		RealSubject realSubject = new RealSubject();
		MyHandler handler = new MyHandler();
		handler.setRealSubject(realSubject);
		
		Subject proxySubject = (Subject)Proxy.newProxyInstance(RealSubject.class.getClassLoader(), realSubject.getClass().getInterfaces(), handler);
		proxySubject.sailBook();
	}
}

測試結果:
打折
賣書
贈送代金券