`
Col.Man
  • 浏览: 18326 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

java代理模式

阅读更多

代理模式

代理模式

   代理模式就是一个人或者一个机构代表一个人或一个机构采取行动。在一些情况下,一个客户不想或者不能直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

代理模式的结构

代理模式所涉及的角色有:

  • 抽象主题角色:声明了真实主题和代理主题的共同接口,这样一来在任何可以使用真实主题地方都可以使用代理对象。
  • 代理主题角色:代理主题内部含有真实主题的引用,从而可以在任何时候操作真实主题对象;代理主题提供一个与真实主题相同的接口,以便可以在任何时候替代真实主题。代理主题通常在客户端调用传递给真实主题之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象。
  • 真实主题角色:定义了代理角色所代表的真实对象。

结构图:



 代码清单:


 抽象主题角色:

abstract public class Subject
{
    abstract public void request();
}

 
 真实主题角色

public class RealSubject extends Subject 
{
	public RealSubject()
	{ 
	}
	
	public void request()
	{ 
		System.out.println("From real subject.");
	}
}

 代理主题角色

public class ProxySubject extends Subject {
	private RealSubject realSubject;

	public ProxySubject() {
	}

	public void request() {
		preRequest();

		if (realSubject == null) {
			realSubject = new RealSubject();
		}

		realSubject.request();

		postRequest();
	}

	private void preRequest() {
		// something you want to do before requesting
	}

	private void postRequest() {
		// something you want to do after requesting
	}
}

客户端

public class Client
{
  	private static Subject subject;

    static public void main(String[] args)
	{ 
		subject = new ProxySubject();
		subject.request();
	}
}

  代理模式的序列图



 ps:不知道为什么客户端请求的序号是2:request().

 

java对代理模式的支持

 

反射(Reflection)与动态代理

    java通过java.lang.refection库中提供的三个类直接支持代理模式:Proxy,InvocationHandler和Method。

    其中Proxy类能够使设计师在运行时创建代理对象,类图如下所示:

 

当系统有了一个代理对象后,对原对象的方法调用首先会被分派给一个调用处理器(Invocation Handler).InvocationHandler类图如下:



 程序可以在调用处理器的invoke 方法时截获这个调用,进行额外的操作。

设计师可以按照以下步骤创建动态代理:

  1. 声明一系列接口来创建代理对象。
  2. 创建一个调用处理器对象(InvocationHandler)。
  3. 将这个代理指定给某个其他对象的代理。
  4. 在调用处理器的Invoke()方法中采取代理,一方面将调用传递给真实对象,另一方面执行各种需要做的操作。
 一个例子:

    这个例子要解决的问题是为一个Vector对象提供一个代理对象,当Vector的任何方法在调用之前和之后都打印两条信息,这表明代理对象有能力截获和控制这个Vector对象。

   根据动态代理的创建步骤,我们只需要一个VectorProxy类,此类需要实现InvocationHandler接口,如下图:

 

 

 代码如下:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.lang.reflect.Method;
import java.util.Vector;
import java.util.List;

public class VectorProxy implements InvocationHandler {
	private Object proxyobj;

	/** @link dependency */
	/* #Proxy lnkProxy; */

	public VectorProxy(Object obj) {
		proxyobj = obj;
	}

	public static Object factory(Object obj) {
		Class cls = obj.getClass();

		return Proxy.newProxyInstance(cls.getClassLoader(),
				cls.getInterfaces(), new VectorProxy(obj));
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("before calling " + method);

		if (args != null) {
			for (int i = 0; i < args.length; i++) {
				System.out.println(args[i] + "");
			}
		}

		Object o = method.invoke(proxyobj, args);

		System.out.println("after calling " + method);

		return o;
	}

	public static void main(String[] args) {
		List v = null;

		v = (List) factory(new Vector(10));

		v.add("New");
		v.add("York");
		v.remove(0);
	}
}

 

 输出信息
before calling public abstract boolean java.util.List.add(java.lang.Object)
New
after calling public abstract boolean java.util.List.add(java.lang.Object)
before calling public abstract boolean java.util.List.add(java.lang.Object)
York
after calling public abstract boolean java.util.List.add(java.lang.Object)
before calling public abstract java.lang.Object java.util.List.remove(int)
0
after calling public abstract java.lang.Object java.util.List.remove(int)

 摘自《Java与模式》

  • 大小: 17.2 KB
  • 大小: 17.1 KB
  • 大小: 10.4 KB
  • 大小: 5.7 KB
  • 大小: 24.1 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics