码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式入门之代理模式Proxy

时间:2014-04-28 10:27:41      阅读:253      评论:0      收藏:0      [点我收藏+]

标签:设计模式   代理模式   proxy   

//代理模式定义:为其他对象提供一种代理以控制对这个对象的访问
//实例:鉴于书中给出的例子不太好,而且有些疑问,所以直接用保护代理作为实例
//要求,一旦订单被创建,只有订单的创建人才可以修改订单中的数据,其他人则不能修改
//这里,代理模式的作用是做访问控制,即在访问对象时,中间加一个中转
public interface OrderApi {
	public String getProductName();
	public void setProductName(String productName,String user);
	public int getOrderNum();
	public void setOrderNum(int orderNum,String user);
	public String getOrderUser();
	public void setOrderUser(String orderUser,String user);
}
public class Order implements OrderApi {
	private String productName;
	private int orderNum;
	private String orderUser;
	public Order(String productName,int orderNum,String orderUser) {
		this.productName = productName;
		this.orderNum = orderNum;
		this.orderUser = orderUser;
	}
	//get,set methods
}
public class OrderProxy implements OrderApi {
	private Order order = null;
	public OrderProxy(Order realSubject) {
		this.order = realSubject();
	}
	public void setProductName(String productName,String user) {
		//控制访问权限,只有创建订单的人员才能够修改
		if(user!=null && user.equals(this.getOrderUser())) {
			order.setProductName(productName,user);
		}else {
			System.out.println("对不起"+user+",您没有修改产品名称的权限");
		}
	}
	//同样,以下是setOrderNum和setOrderUser,及get方法,省略
}
public class Client {
	public static void main(String[] args) {
		OrderApi order = new OrderProxy(new Order("设计模式",100,"张三"));
		order.setOrderNum(123,"李四");
		//这个设置是无效的,因为李四没有修改张三订单的权限
	}
}
//以上是自己写出的代理,其实Java对代理模式提供了内建的支持
//在java.lang.reflect包下,提供了一个Proxy的类和一个InvocationHandler的接口
//通常把我们自己写的代理叫做Java的静态代理,因为如果Subject接口发生变化,那么代理类
//和具体的目标实现都要变化,不够灵活
//而把Java中内建的对代理模式叫做Java的动态代理,动态代理跟静态代理相比,明显的变化是:
//动态代理实现的时候,虽然Subject接口上定义了很多方法,但是动态代理类始终只有一个invoke方法
//这样,当Subject接口发生变化的时候,动态代理的接口就不需要跟着变化了
//看实例
public class DynamicProxy implements InvocationHandler {
	private OrderApi order = null;
	public Order getProxyInterface(Order order) {
		this.order = order;
		OrderApi orderApi = (OrderApi)Proxy.newProxyInstance(
							order.getClass().getClassLoader(),
							order.getClass().getInterfaces(),
							this);
		return orderApi;
	}
	public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
		if(method.getName().startsWith("set")) {
			if(order.getOrderUser()!=null && order.getOrderUser().equals(args[1])) {
				return method.invoke(order,args);
			}else {
				//无权限
			}
		}else {
			return method.invoke(order,args);
		}
	}
}
public class Client {
	public static void main(String[] args) {
		Order order = new Order("设计模式",100,"张三");
		DynamicProxy dynamicProxy = new DynamicProxy();
		OrderApi orderApi = dynamicProxy.getProxyInterface(order);
		orderApi.setOrderNum(123,"李四");
		//实际使用的是经过加工的set方法
		//无权限
	}
}
//代理模式的本质:控制对象访问
//既然本质是控制对象访问,意思就是在访问者与原始对象之间加一个代理即可
//同理,代理模式也可以通过继承原始类来实现,让访问者操作继承类,继承类来控制原始对象的访问
//从而实现控制对象访问的目的
//何时选用代理模式
//1.需要为一个对象在不同的地址空间提供局部(重点)代表的时候,可以使用远程代理
//2.需要按照需要创建开销很大的对象的时候,可以使用虚代理(即一个不完整的对象)
//3.需要控制对原始对象的访问的时候,可以使用保护代理,上边即保护代理实例
//4.需要在访问对象执行一些附加操作的时候,可以使用智能指引代理

设计模式入门之代理模式Proxy

标签:设计模式   代理模式   proxy   

原文地址:http://blog.csdn.net/herewjxiang/article/details/24619789

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!