欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

匿名内部类代理模式

程序员文章站 2024-01-24 09:26:58
...

项目中web网页请求,action层返回的是同一个对象,WebApiBaseResult,并使用相同的异常处理

@RequestMapping(value="/path",method = RequestMethod.GET)
@ResponseBody
public WebApiBaseResult path(HttpSession httpSession
		,HttpServletRequest request
		,@RequestParam(value = "condition",required = false)String condition
		,@RequestParam(value = "keyword",required = false)String keyword){
	WebApiBaseResult result = new WebApiBaseResult();//web统一返回对象
	try{
		BaseUserModel  baseUser = (BaseUserModel) httpSession.getAttribute("currentUser");
		if(null == baseUser){
			throw new NotLogException("用户登录过期,请重新登录");
		}
		//获取session中的登录公司的信息
		BaseCompanyModel baseCompany = (BaseCompanyModel)httpSession.getAttribute("currentCompany");
		//业务代码
        ....................
        result.setData(data);//返回数据统一放在data里
	}catch(NotLogException e){
		logger.error(MyRequestUtils.getParameterString());
		logger.error(e.getMessage(),e);
		result.setStatusCode(StatusCodeEnum.NOTLOG.getCode());
		result.setMessage(e.getMessage());
		return result;
	}catch(Exception e){
		logger.error(MyRequestUtils.getParameterString());
		logger.error(e.getMessage(),e);
		result.setStatusCode(StatusCodeEnum.COMMONERROR.getCode());
		result.setMessage(e.getMessage());
		return result;
	}
	return result;
}

所有的web请求都是如此处理的,虽然复制粘贴一下也不费什么事,但是主管还是想复用一下,代码看起来也清爽一点,于是我参考了一下过去项目的实现代码,基本原理就是匿名函数和代理的编程思想的结合。

首先是写一个接口,专门用来当匿名函数的

public interface BaseActionCallBack {
	WebApiBaseResult run() throws Exception;
}

就这么简单,也不用实现,是专门当匿名函数用的。

再写一个代理类

public class BaseActionProxy {
	public static WebApiBaseResult commonWebAction(Logger logger, BaseActionCallBack action) {
		WebApiBaseResult result = null;
		try {
			result = action.run();
		} catch (NotLogException e) {
			result = new WebApiBaseResult();
			logger.error(MyRequestUtils.getParameterString());
			logger.error(e.getMessage(), e);
			result.setStatusCode(StatusCodeEnum.NOTLOG.getCode());
			result.setMessage(e.getMessage());
		} catch (Exception e) {
			result = new WebApiBaseResult();
			logger.error(MyRequestUtils.getParameterString());
			logger.error(e.getMessage(), e);
			result.setStatusCode(StatusCodeEnum.COMMONERROR.getCode());
			result.setMessage(e.getMessage());
		}
		return result;
	}
}

将上面写的接口类当做参数传进去,然后我还加了一个logger参数,打印异常用。

接着最开始的代码就可以改造成这样

@RequestMapping(value="/path",method = RequestMethod.GET)
@ResponseBody
public WebApiBaseResult path(HttpSession httpSession
		,HttpServletRequest request
		,@RequestParam(value = "condition",required = false)String condition
		,@RequestParam(value = "keyword",required = false)String keyword){
		return BaseActionProxy.commonWebAction(logger, new BaseActionCallBack() {
			@Override
			public WebApiBaseResult run() throws Exception {
				WebApiBaseResult result = new WebApiBaseResult();
				BaseUserModel  baseUser = (BaseUserModel) httpSession.getAttribute("currentUser");
				if(null == baseUser){
					throw new NotLogException("用户登录过期,请重新登录");
				}
				//获取session中的登录公司的信息
				BaseCompanyModel baseCompany = (BaseCompanyModel)httpSession.getAttribute("currentCompany");
				//业务代码
        		....................
        		result.setData(data);//返回数据统一放在data里
				return result;
			}
		});
}

看起来是不是简洁了很多,不过值得注意的是,匿名函数类里面不能使用非finial的变量。java1.8比较智能一点,只要你没有给变量赋值他就会视为最终变量。这样就会造成一些麻烦。比如分页参数,因为hibernate分页是从0开始的,所以分页参数传进来后要减1,但是在匿名函数中就不能直接用了。

@RequestMapping(value="/path",method = RequestMethod.GET)
@ResponseBody
public WebApiBaseResult path(HttpSession httpSession
		,HttpServletRequest request
		,@RequestParam(value = "condition",required = false)String condition
		,@RequestParam(value = "keyword",required = false)String keyword
		,@RequestParam(value = "page",required = false)Integer page){
		    return BaseActionProxy.commonWebAction(logger, new BaseActionCallBack() {
			@Override
			public WebApiBaseResult run() throws Exception {
				WebApiBaseResult result = new WebApiBaseResult();
				BaseUserModel  baseUser = (BaseUserModel) httpSession.getAttribute("currentUser");
				if(null == baseUser){
					throw new NotLogException("用户登录过期,请重新登录");
				}
				//获取session中的登录公司的信息
				BaseCompanyModel baseCompany = (BaseCompanyModel)httpSession.getAttribute("currentCompany");
				Integer p = 0;//页码数需要减1,但是匿名函数中不能改变变量,所以只能声明一个新的变量
				if (page != null)
					p = page -1;
				PageParam pageInfo = new PageParam(p, size, pageFlag, sort);
				//业务代码
        		....................
        		result.setData(data);//返回数据统一放在data里
				return result;
			}
		});
}

只能声明一个新的变量来接收,从这一点上看就不够优雅了。相当于给代码加了一个限制。。。其实还好,就是如果基本类型做更改需要声明新变量接收,如果是对象,那么还是能够做更改的,就是其引用不能改变。

建议还是在action层中使用,然后把主要的业务代码放到service层,action层只作为传递参数的结构,这样基本就不会出问题了。

相关标签: 代理 匿名函数