设计模式-代理模式

代理:  我提供一些服务,但我不直面客户,由代理商来跟客户交涉。

案例:  使用代理,来模拟MVC中 C

代理应用场景:

Proxy模式常见情况:
1) 远程代理(Remote  Proxy)为一个位于不同的地址空间的对象提供一个本地的代理对象。这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又叫做大使(Ambassador)
2) 虚拟代理(Virtual Proxy)根据需要创建开销很大的对象。如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。 
3) 保护代理(Protection Proxy)控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。
4) 智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。
5) Copy-on-Write代理:它是虚拟代理的一种,把复制(克隆)操作延迟到只有在客户端真正需要时才执行。一般来说,对象的深克隆是一个开销较大的操作,Copy-on-Write代理可以让这个操作延迟,只有对象被用到的时候才被克隆。

静态代理模式UML图:

     

类介绍: 

UParamAttr  参数绑定注解(方法参数注解)

        URequestMapper :请求路径注解 (方法注解)

        UAction                   :action类注解

        UserAction : 用户action类(服务提供者)

       ActionProxy :  action代理类(代理商)

        ActionProxyFactory:  工厂类,用来获取代理 

        DB:   假数据库 

       URequest  :请求数据简单封装,模拟HTTP request

       User  : 实体bean

       TestMain: 测试类

 

代码截图如下:

      

action类标记注解
package com.bo.proxy;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
 * @Target 说明了Annotation所修饰的对象范围:
 * 	Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、
 * 			类型成员(方法、构造方法、成员变量、枚举值)、
 *          方法参数和本地变量(如循环变量、catch参数)。
 *       	在Annotation类型的声明中使用了target可更加明晰其修饰的目标
 *       
 *  @Retention定义了该Annotation被保留的时间长短:
 *  				某些Annotation仅出现在源代码中,而被编译器丢弃;
 *  				而另一些却被编译在class文件中;
 *  				编译在class文件中的Annotation可能会被虚拟机忽略,
 *  				而另一些在class被装载时将被读取(请注意并不影响class的执行,因为Annotation与class在使用上是被分离的)。
 *  				使用这个meta-Annotation可以对 Annotation的“生命周期”限制。     
 */
@Retention(value=RetentionPolicy.RUNTIME)
@Target(value=ElementType.TYPE)
/**
 * action标记
 * @author 波
 *
 */
public @interface UAction { 
	public String value() default ""; 
}

参数绑定注解:
package com.bo.proxy;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 参数绑定注解
 * @author 波
 *
 */
@Retention(value=RetentionPolicy.RUNTIME)
@Target(value=ElementType.PARAMETER)
public @interface UParamAttr {
	public String value() default ""; 
}

请求路径注解:
package com.bo.proxy;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 请求路径注解
 * @author 波
 *
 */
@Retention(value=RetentionPolicy.RUNTIME)
@Target(value=ElementType.METHOD)
public @interface URequestMapper {
	String value() default "";
}

用户控制类action:
package com.bo.proxy;

import java.util.List;

@UAction
public class UserAction  {
	 @URequestMapper("/list")
	  public List<User> list(){
		  return DB.queryUserList();
	  }
	 @URequestMapper("/add")
	 public Object addUser(@UParamAttr("userinfo") User u){
		 return DB.addUser(u);
	 }
	 @URequestMapper("/remove")
	 public Object removeUser(@UParamAttr("userinfo") User u){
		 return DB.removeUser(u);
	 }
}


action代理类:
package com.bo.proxy;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class ActionProxy implements InvocationHandler {
	private Object object;
	
	public ActionProxy(Object object) {
		// TODO Auto-generated constructor stub
		this.object = object;
	}
	public void before(){}
	public void after(){}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		this.before();
		Object object = method.invoke(this.object, args);
		this.after();
		return object;
	}
	
	public Object execute(URequest request) throws Throwable{
		String path = request.getPath();
		Map<String,Object> requestParam =  request.getRequestParam();
		Object result =null;
		Method[] methods = this.object.getClass().getMethods();
		for(int index=0;index<methods.length;index++){
			Method method = methods[index];
			URequestMapper uRequestMapper = method.getAnnotation(URequestMapper.class);
			if(uRequestMapper!=null){
				String mapperPath = uRequestMapper.value();
				if(mapperPath.equals(path)){
					Class<?>[] cls = method.getParameterTypes();
					Annotation[][] paraAnnotations = method.getParameterAnnotations();
					Object[] args =  new Object[cls.length];
					for(int paraAnnIndex=0;paraAnnIndex<paraAnnotations.length;paraAnnIndex++){
						Annotation[] annotaion = paraAnnotations[paraAnnIndex];
						for(int cParaAnnIndex=0;cParaAnnIndex<annotaion.length;cParaAnnIndex++){
							Annotation tAnnotaion = annotaion[cParaAnnIndex];
							if(tAnnotaion instanceof UParamAttr){
								UParamAttr uParamAttr=(UParamAttr)tAnnotaion;
								String paramKey = uParamAttr.value();
								//Object obj = cls[paraAnnIndex].newInstance();
								args[paraAnnIndex] =requestParam.get(paramKey);
							}
						}
					}
					result = method.invoke(this.object, args);//this.invoke(this.object, method, args) ;//this.invoke(this.object, args);
					/*for(int ptIndex=0;ptIndex<cls.length;ptIndex++){
						cls[ptIndex];
					}*/
					break;
				}
			}
		}
		return result;
	}
}

代理工厂类:
package com.bo.proxy;

public class ActionProxyFactory {
	public static Object newInstaces(Class cls) throws IllegalArgumentException, InstantiationException, IllegalAccessException{
//		return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), cls.getInterfaces(),);
		return new ActionProxy(cls.newInstance());
	}
}

假数据库:
package com.bo.proxy;

import java.util.ArrayList;
import java.util.List;

public class DB {
	private static List<User> userList = new ArrayList<>();
			
	static{
		userList = (userList!=null? userList:new ArrayList<User>());
		for(int i=0;i<5;i++){
			User u = new User();
			u.setUid("uid00"+i);
			u.setUname("uname00"+i);
			userList.add(u);
		}
	}	
	
	public static List<User> queryUserList(){
		return DB.userList;
	}
	
	public static boolean removeUser(User u){
		return DB.userList.remove(u);
	}
	
	public static boolean addUser(User u){
		return DB.userList.add(u);
	}
}

请求数据封装-模拟http request:
package com.bo.proxy;

import java.util.Map;

public class URequest {
	private String path ;
	private Map<String,Object> requestParam ;
	public String getPath() {
		return path;
	}
	public void setPath(String path) {
		this.path = path;
	}
	public Map<String, Object> getRequestParam() {
		return requestParam;
	}
	public void setRequestParam(Map<String, Object> requestParam) {
		this.requestParam = requestParam;
	}
}

测试类:
package com.bo.proxy;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TestMain {

	public static void main(String[] args) throws Throwable {
		// TODO Auto-generated method stub
		ActionProxy proxy = (ActionProxy) ActionProxyFactory.newInstaces(UserAction.class);
		
		System.out.println("添加用户:");
		URequest  	addRequest = new URequest();
		addRequest.setPath("/add");
		Map<String,Object> userInfo = new HashMap<>();
		User u = new User();
		u.setUid("uid-0001");
		u.setUname("uname-0001");
		userInfo.put("userinfo", u);
		addRequest.setRequestParam(userInfo);
		boolean b = (boolean) proxy.execute(addRequest);
		System.out.println(b?"添加成功":"添加失败");
		
		System.out.println("所有用户列表:");
		URequest  	request = new URequest();
		request.setPath("/list");
		List<User> list = (List<User>) proxy.execute(request);
		
		for(int index = 0;index<list.size();index++){
			System.out.println(list.get(index).toString());
		}
	}

}
输出:
添加用户:
添加成功
所有用户列表:
User [uid=uid000, uname=uname000]
User [uid=uid001, uname=uname001]
User [uid=uid002, uname=uname002]
User [uid=uid003, uname=uname003]
User [uid=uid004, uname=uname004]
User [uid=uid-0001, uname=uname-0001]


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值