减少Cyclomatic复杂性的最佳方法

时间:2015-03-04 06:58:32

标签: java performance design-patterns cyclomatic-complexity

下面的方法具有13的圈复杂度我遵循一些使用三元运算符的方法用于小的if else,但对于长码,什么是最好的方法 什么设计模式用于resuce if else条件或任何其他方式来减少圈复杂度sonarQube显示Cyclomatic Complexity错误。 我是新手,帮助我修改过程

  @RequestMapping(value = "/submitUser", method=RequestMethod.POST)
            public String submitUser(@ModelAttribute User userBean,Locale locale, RedirectAttributes redirectAttributes, HttpSession session, Model model) {
        boolean status = false, isAdd = false;
        String imagePath = "", task = "";
        isAdd = userBean.getAdd();
        /*if(isAdd) {
                    task = "add";
                } else {          // replace this by task=isAdd?"add":"edit";
                    task = "edit"; //
                }*/
                GlobalLogger.logApplicationDebugLog("Received request to " + task + " user ", LOGGER);
        if (session != null && session.getAttribute("UserImagePath") != null) {
            imagePath = session.getAttribute("UserImagePath").toString();
                }
                int currentUserId = Integer.parseInt(session.getAttribute(SessionKeyConstants.USER_ID).toString());
                try {
                    status = iuser.submitUser(userBean, imagePath,currentUserId);
                    if(isAdd) {
                        if (status) {
                            GlobalLogger.logInfoLog("User "+userBean.getUserName()+" has been " + task + "ed successfully", LOGGER);
                            redirectAttributes.addFlashAttribute("successMsg", messageSource.getMessage("operationMsg.addUserSuccess", new String[] {userBean.getEmpEmail()}, locale));
                            return "redirect:/users.action";
                        } else {
                            GlobalLogger.logApplicationDebugLog("Error in adding user "+userBean.getUserName(), LOGGER);
                            redirectAttributes.addFlashAttribute("errorMsg", messageSource.getMessage("operationMsg.addUserFailure", new String[] {}, locale));
                            redirectAttributes.addFlashAttribute("isAdd", isAdd);
                            redirectAttributes.addFlashAttribute("userBean", userBean);
                            return "redirect:/addUser.action?isAdd=true";
                        }
                    } else {
                        if (status) {
                            GlobalLogger.logInfoLog("User "+userBean.getUserName()+" has been " + task + "ed successfully", LOGGER);
                            redirectAttributes.addFlashAttribute("successMsg", messageSource.getMessage("label.addSuccessMsg", new String[] {userBean.getFirstName()}, locale));
                            return "redirect:/users.action";
                        } else {
                            GlobalLogger.logApplicationDebugLog("Error in adding user "+userBean.getUserName(), LOGGER);
                            redirectAttributes.addFlashAttribute("errorMsg", messageSource.getMessage("label.addFailedMsg", new String[] {userBean.getFirstName()}, locale));
                            redirectAttributes.addFlashAttribute("isAdd", isAdd);
                            redirectAttributes.addFlashAttribute("userBean", userBean);
                            return "redirect:/addUser.action?isAdd=false";
                        }
                    }
                } catch (UserException e) {
                    GlobalLogger.logApplicationDebugLog("User Name or Employee Id exists for user "+userBean.getUserName(), LOGGER);
                    redirectAttributes.addFlashAttribute("userBean", userBean);
                    redirectAttributes.addFlashAttribute("errorMsg", messageSource.getMessage(e.getErrorcode(), new String[] {}, locale));
                    return "redirect:/addUser.action?isAdd=true";
                }
            }

1 个答案:

答案 0 :(得分:2)

使用太长时间方法解决问题的最直接方法就是将它们分解成碎片。将方法的一部分提取到从原始方法调用的单独方法中。通常它可以通过IDE自动完成,例如Eclipse(菜单Refactor / Extract方法)。

在你的方法中,你有几乎相同的isAdd == true和false的代码。您可以将此代码提取到单独的方法,例如。 String redirectUser(boolean isAdd, boolean status, <other attribs>) {...}。那么你的方法就会简单得多。

第一个变化很简单 - 提取方法(这可以自动完成):

    @RequestMapping(value = "/submitUser", method=RequestMethod.POST)
public String submitUser(@ModelAttribute User userBean,Locale locale, RedirectAttributes redirectAttributes, HttpSession session, Model model) {
    boolean status = false, isAdd = false;
    String imagePath = "", task = "";
    isAdd = userBean.getAdd();
    GlobalLogger.logApplicationDebugLog("Received request to " + task + " user ", LOGGER);
    if (session != null && session.getAttribute("UserImagePath") != null) {
        imagePath = session.getAttribute("UserImagePath").toString();
    }
    int currentUserId = Integer.parseInt(session.getAttribute(SessionKeyConstants.USER_ID).toString());
    try {
        status = iuser.submitUser(userBean, imagePath,currentUserId);
        return redirectUser(userBean, locale, redirectAttributes, status,
                isAdd, task);
    } catch (UserException e) {
        GlobalLogger.logApplicationDebugLog("User Name or Employee Id exists for user "+userBean.getUserName(), LOGGER);
        redirectAttributes.addFlashAttribute("userBean", userBean);
        redirectAttributes.addFlashAttribute("errorMsg", messageSource.getMessage(e.getErrorcode(), new String[] {}, locale));
        return "redirect:/addUser.action?isAdd=true";
    }
}

private String redirectUser(User userBean, Locale locale,
        RedirectAttributes redirectAttributes, boolean status,
        boolean isAdd, String task) {
    if(isAdd) {
        if (status) {
            GlobalLogger.logInfoLog("User "+userBean.getUserName()+" has been " + task + "ed successfully", LOGGER);
            redirectAttributes.addFlashAttribute("successMsg", messageSource.getMessage("operationMsg.addUserSuccess", new String[] {userBean.getEmpEmail()}, locale));
            return "redirect:/users.action";
        } else {
            GlobalLogger.logApplicationDebugLog("Error in adding user "+userBean.getUserName(), LOGGER);
            redirectAttributes.addFlashAttribute("errorMsg", messageSource.getMessage("operationMsg.addUserFailure", new String[] {}, locale));
            redirectAttributes.addFlashAttribute("isAdd", isAdd);
            redirectAttributes.addFlashAttribute("userBean", userBean);
            return "redirect:/addUser.action?isAdd=true";
        }
    } else {
        if (status) {
            GlobalLogger.logInfoLog("User "+userBean.getUserName()+" has been " + task + "ed successfully", LOGGER);
            redirectAttributes.addFlashAttribute("successMsg", messageSource.getMessage("label.addSuccessMsg", new String[] {userBean.getFirstName()}, locale));
            return "redirect:/users.action";
        } else {
            GlobalLogger.logApplicationDebugLog("Error in adding user "+userBean.getUserName(), LOGGER);
            redirectAttributes.addFlashAttribute("errorMsg", messageSource.getMessage("label.addFailedMsg", new String[] {userBean.getFirstName()}, locale));
            redirectAttributes.addFlashAttribute("isAdd", isAdd);
            redirectAttributes.addFlashAttribute("userBean", userBean);
            return "redirect:/addUser.action?isAdd=false";
        }
    }
}

现在,您可以比较if的两种情况,因为它们非常相似。也许你可以重写它们以避免重复。例如,而不是返回&#34;重定向:/ addUser.action?isAdd = true&#34 ;;你可以写return&#34;重定向:/ addUser.action?isAdd =&#34; + isAdd。

重构是一个迭代过程。您应该进行小的更改,运行单元测试以确保没有任何损坏,并重复直到结果令人满意。