常见设计模式之Proxy篇

根据Design Pattern描述,常用Proxy设计模式分为四种:virtual proxy, remote proxy,protection proxy和smart reference,相应的句子如下:

1. A remote proxy provides a local representative for an object in a different address space

2. A virtual proxy creates expensive objects on demand.

3. A protection proxy controls access to the original object. Protection proxies are useful when objects should have different access rights.

4.A smart reference is a replacement for a bare pointer that performs a additional actions when an object is accessed. Typical uses include

   ① counting the number of reference to the real object so that it can be freed automatically when there are no more references(also called smart pointer)

   ② loading a persistent object into memory when it's first referenced

   ③ checking that the real object is locked before it's accessed to ensure that no other object can change it.

remote proxy 保存为一个远端对象的引用,当Client需要相应的方法时,会把访问的参数传递给本地的一个proxy对象,然后本地的proxy对象将参数进行编码转发给远端的实际对象。virtual proxy往往用于延迟初始化,对于一些对象的构建比较复杂和消耗空间和性能时,我们往往会使用延迟初始化这样的技术。通过这种代理模式,能将复杂对象的初始化给封装好,而客户端直接与代理进行交互,当实际要使用相应的方法时,才进行实例化具体对象并转发相应的方法给具体的对象。也就是说,对于客户端来讲,Proxy和Real Object直接并无区别。一般来说,当实际初始化Real Object后,Proxy会保存其一个引用。

下面就写一个protection proxy的静态代理和动态代理的例子。

package net.liuyx.test;

public class ProxyTest {
	public static void main(String[] args){
		Bureau iface = (Bureau) new Secretary();
		iface.sign();
		iface.eat();
	}
}
//某局
interface Bureau{
	void sign();
	void eat();
}
//请局长吃饭和签字要经过秘书这一关
class Secretary implements Bureau{
	private final Head head;
	Secretary(){
		head = new Head();
	}
	public void sign(){
		head.sign();
	}
	public void eat(){
		head.eat();
	}
	private static class Head implements Bureau{
		public void sign(){System.out.println("header sign!");}
		 public void eat(){System.out.println("ask the head to eat successly");};
	}
}
其输出为

很显然,局长这个类被秘书给保护起来了,转发给局长的方法都会经过秘书这个代理。下面写一个关于动态代理的实现。动态代理会多一个InvocationHandler类的实现,该类用来为代理转发具体的参数:

package net.liuyx.test;

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

public class ProxyTest {
	public static void main(String[] args) {
		Bureau head = (Bureau) new Head();
		Bureau secretary = (Bureau) Proxy.newProxyInstance(Bureau.class
				.getClassLoader(), new Class[] { Bureau.class },
				new DefaultHandler(head));//动态产生代理,在第二个Demo中,并没有为Secretary写代码,Proxy的这个静态方法会动态产生一个代理,该方法需要穿几个参数:ClassLoad对象,被代理对象实现的接口列表(记住,是接口列表,不包含抽象类),和一个InvocationHandler对象
		doSomething(secretary);
	}
	public static void doSomething(Bureau b){
		b.eat();
		b.sign();
	}
}

// 某局
interface Bureau {
	void sign();

	void eat();
}

class Head implements Bureau {

	@Override
	public void sign() {
		System.out.println("header sign!");
	}

	@Override
	public void eat() {
		System.out.println("ask the head to eat successly");
	}
}

class DefaultHandler implements InvocationHandler {
	Object proxied;

	DefaultHandler(Object proxied) {
		this.proxied = proxied;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("proxy handler the request to the real object");
		System.out.println("It's method is: " + method.getName()
				+ " and is params is " + args);
		return method.invoke(proxied, args);//InvocationHandler的精髓就在这个方法里了,通过反射调用实际被代理对象的方法,并传进参数
	}

}

输出:


其他几种代理模式的编写方法也类似,在此就不赘述了。只不过在Virtual Proxy模式中,在具体操作被代理对象时才实例化对象,比如调用eat 和sign时才实例化该对象,而不是在构造器中实例化。

其实Protection proxy代理模式有点像Decorator模式,但装饰器模式往往是给一个对象动态添加一个或多个职责,两者的出发点不一样。而protected的出发点是为了控制实际对象的访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值