zoukankan      html  css  js  c++  java
  • 设计模式入门之代理模式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.须要在訪问对象运行一些附加操作的时候。能够使用智能指引代理

  • 相关阅读:
    elastic-job-console
    CentOS7_安装mysql5.7
    CentOS7_开放指定端口
    CentOS7_防火墙
    Docker-CentOS7-安装
    MySQL_写锁_lock tables tableName write
    cesium 动态流动纹理
    cesium加载二维贴地的地名(本地地名数据)
    python3.6安装open AI gym环境(windows)
    python PIL打开较大的tif影像时出错-OSError: cannot identify image file Image.open
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5199154.html
Copyright © 2011-2022 走看看