论坛首页 入门技术论坛

这段代码怎样重构?

浏览 6033 次
该帖已经被评为新手帖
作者 正文
   发表时间:2007-02-27  
代码如下
public class OrderManagerActions extends BaseAction {

	/** 
	 * 创建新订单
	 */
	public ActionForward create(
		ActionMapping mapping,
		ActionForm form,
		HttpServletRequest request,
		HttpServletResponse response) {
		
		LoginUser loginUser = getLoginUser(request);
		if( !loginUser.isLogin() ){
			//go to login
		}
		
		CustomOrder order = new CustomOrder();
                   //省略order.setXXX();
		OrderManager orderManager = getOrderManager();
		try {
			orderManager.createOrder(order);
		} catch (OrderException e) {
		}
		
		return mapping.findForward("saveSuccess");
	}
	
	/**
	 * 查看订单
	 */
	public ActionForward list(
			ActionMapping mapping,
			ActionForm form,
			HttpServletRequest request,
			HttpServletResponse response) {
		
		LoginUser loginUser = getLoginUser(request);
		if( !loginUser.isLogin() ){
			//go to login
		}
		
		OrderManager orderManager = getOrderManager();
		List orders = orderManager.findOrderByCustomId(loginUser.getCustomId());
		
		request.setAttribute("orders", orders);
		return mapping.findForward("list");
	}

}


这段代码有重复
LoginUser loginUser = getLoginUser(request);
		if( !loginUser.isLogin() ){
			//go to login
		}


问怎么重构能使以上代码最简单? (不使用过滤器或者拦截器)
   发表时间:2007-02-27  
这个不是很简单么?
抽取成一个方法就可以了。
private checkLogin(HttpServletRequest request){
         LoginUser loginUser = getLoginUser(request);  
         if( !loginUser.isLogin() ){  
             //go to login  
         }  
}
 public ActionForward create(  
         ActionMapping mapping,  
         ActionForm form,  
         HttpServletRequest request,  
         HttpServletResponse response) {  
         checkLogin(request);
         ..
} 
...
0 请登录后投票
   发表时间:2007-02-27  
这样在每个方法里还要调用checkLogin。
我是希望只调用一次checkLogin方法
0 请登录后投票
   发表时间:2007-02-27  
最好的方式是用filter拦截,没有登陆的自动跳到登陆界面去,
acegi的filter也可以做到
0 请登录后投票
   发表时间:2007-02-27  
从楼主贴的代码看,是一个web action,在action的方法执行前都要判断用户是否已经登陆,不登陆的话则执行登陆操作。这种安全机制是非常“丑陋”的,所以这块代码的重构不是简单的进行代码整合,而是重新把系统的签权和授权机制进行重构,重构的思路如下:
方法1:采用j2ee的JAAS声明性安全
方法2:通过filter来校验但前会话用户是否已经登陆

重构后,action不再关注是否登陆这样的逻辑,而仅关注操作本身。
0 请登录后投票
   发表时间:2007-02-27  
方法1:
使用AOP(filter也可)封装验证login逻辑
优点:
概念正交,职责分明。
缺点:
不直观。

方法2:
封装变化
interface ActionProcessor{
        ActionForward process(   
                ActionMapping mapping,   
                ActionForm form,   
                HttpServletRequest request,   
                HttpServletResponse response) ;
}

abstract class AbstractAction extends BaseAction{
        protected final ActionForward processWithLogin(   
                ActionMapping mapping,   
                ActionForm form,   
                HttpServletRequest request,   
                HttpServletResponse response,
                ActionProcessor processor) { 
                LoginUser loginUser = getLoginUser(request);   
                if( !loginUser.isLogin() ){   
                    //go to login   
                } 
                return processor.process(mapping, form, request, response);
        }
}

public class OrderManagerActions extends AbstractAction {   
    /**   
     * 创建新订单  
     */  
    public ActionForward create(   
        ActionMapping mapping,   
        ActionForm form,   
        HttpServletRequest request,   
        HttpServletResponse response) {   
        return processWithLogin(createActionProcessor);   
    }   
       
    /**  
     * 查看订单  
     */  
    public ActionForward list(   
            ActionMapping mapping,   
            ActionForm form,   
            HttpServletRequest request,   
            HttpServletResponse response) {   
        return processWithLogin(listActionProcessor); 
    }   
} 
0 请登录后投票
   发表时间:2007-02-27  
    如何封装变化 楼上继续
0 请登录后投票
   发表时间:2007-02-27  
huangpengxiao 写道
    如何封装变化 楼上继续


写完了啊,其实方案二就是lz代码的语法糖
0 请登录后投票
   发表时间:2007-02-27  
intolong 写道
huangpengxiao 写道
    如何封装变化 楼上继续


写完了啊,其实方案二就是lz代码的语法糖


方法二正是我要找的方法
0 请登录后投票
   发表时间:2007-02-27  
xly_971223 写道
intolong 写道
huangpengxiao 写道
    如何封装变化 楼上继续


写完了啊,其实方案二就是lz代码的语法糖


方法二正是我要找的方法


方法1更加职责分明。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics