论坛首页 Java企业应用论坛

了解代理模式

浏览 4165 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-11-28   最后修改:2008-12-05

简单的了解下代理模式

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

     代理模式包括远程代理,虚拟代理,copy-on-write代理,保护代理,catch代理,防火墙代理,同步化代理,只能引用代理,这些我就不一一介绍,我只是用简单例子,了解什么是代理模式。

     代理模式设计到的角色:

     抽象主题角色:声明了真是主题和代理主题的公共接口,这样可以使用真实主题的地方都可以使用代理主题。

     代理主题角色:代理主题角色内不含有真实主题的引用,从而可以在任何时刻操作真实主题对象,代理主题角色提供一个与真实主题相同的接口,可以在任何时刻替代真实主题控制真实主题引用,负责在需要的时候创建真实主题对象(和删除真实主题对象),代理角色通常再将客户端调用传递给真实主题之前,或之后,都执行谋个操作,而不是单纯的将调用传递给真实主题。

      真实主题角色:定义了代理角色所代表的真实对象

根据例子看看:

abstract public class Subject {
	//定义抽象请求方法
	abstract public void request();
}

 真实主题

public class RealSubject extends Subject{

	public RealSubject(){
		
	}
	public void request() {
		// TODO Auto-generated method stub
		System.out.println("请求");
	}

}

 

代理主题

public class ProxySubject extends Subject{

	private RealSubject realSubject;
	public ProxySubject(){
		System.out.println("进入代理类.......");
	}
	@Override
	public void request() {
		// TODO Auto-generated method stub
		preRequest();
		if(realSubject==null){
			realSubject = new RealSubject();
		}
		realSubject.request();
		postRequest();
	}
	/**
	 * 请求前操作
	 * */
	private void preRequest(){
		System.out.println("请求前");
	}
	/**
	 * 请求后操作
	 * */
	private void postRequest(){
		System.out.println("请求后");
	}

}

 

测试代理

public class TestProxy {
	public static void main(String[] args) {
		Subject s = new ProxySubject();
		s.request();
	}

}

 代理模式的时序图。

 

从这个测试不难看出代理类的作用,代理主题并不改变主题接口,模式的用意是不让客户端感觉到代理的存在,其次,代理使用委派将客户端的调用委派给真实主题对象,代理主题起到的是一个传递作用;最后,代理主题在传递请求之前和之后都可以执行特定的操作,而不是单纯的传递请求。

 

接下来说说动态代理模式

public class VectorProxy implements InvocationHandler{

	private Object proxyobj;
	
	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<String> v = null;
		v = (List) VectorProxy.factory(new Vector(10));
		v.add("New");
		v.add("York");
	}
}

 

运行结果:

before callingpublic abstract boolean java.util.List.add(java.lang.Object)
New
after callingpublic abstract boolean java.util.List.add(java.lang.Object)
before callingpublic abstract boolean java.util.List.add(java.lang.Object)
York
after callingpublic abstract boolean java.util.List.add(java.lang.Object)

 

此例子用了反射,从结果可以看出代理对象截获了对Vector对象的所有调用,在调用传递给Vector之前和之后,代理对象具有采取合适操作的灵活性,虽然这里代理对象所采取的操作就是打印,也可以定义其他操作。

  • 大小: 14.9 KB
   发表时间:2008-12-03  
不知道你的动态可以执行么?

必须得用接口吧,用抽象类好像不行
0 请登录后投票
   发表时间:2008-12-04  
好象是要用接口的,我的代码也是这样写的,用接口实现代理
0 请登录后投票
   发表时间:2008-12-04  
实现代理的时候可以用接口,也可以不用,因为除了jdk里的代理,还可以用cglib来实现的,因为有些时候并没有实现接口。
1 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics