如何避免使controller等控制器的代码膨胀

以下这段代码为例。。。

里面包含了几部分:
1. 从表单获取数据
2. 查询相应数据(具体的业务 一行代码搞定了)
3. 转化为 页面所需要的相关格式
4. 数据排序 并放到map里

我明白“将业务逻辑提取出来放到service”之类的话, 但是这里面确实无任何业务逻辑, 百分之九十以上都是为页面服务的数据转化。 如果放到业务层或者领域层会明显污染业务代码。

请大家以这个为例说说应该如何去做

(如果把一部分map的操作放进facade 或者service , 纯粹的数据加工这类的代码, 放到 这两个层里面 是否合适? 还是有其他的方式? 老实说写完我就觉得乱糟糟了这种代码)

[code="java"]
public ModelAndView tochoose(HttpServletRequest request, HttpServletResponse response) throws Exception {
Map map = new HashMap();

    String buildingNum = request.getParameter("buildingNum");
    String scanCode = request.getParameter("scanCode");
    Validate.notEmpty(scanCode);

    Subscribe sc = subscribeRepository.load(scanCode);

    if (sc != null && sc.isLotteryScan()) {
        // 加载所有楼号
        List<String> allBuildNums = houseChooseService.getAllBuildingNum();
        map.put("sc", new SubscribeViewAdapter(sc));
        map.put("scanCode", scanCode);
        map.put("allBuildingNum", allBuildNums);
    } else {
        return new ModelAndView("choose/error");
    }

    //选择了楼号
    if (null != buildingNum && !"".equals(buildingNum)) {
        //查出小区
        List<Area> allArea = areaRepository.findAll();
        if(allArea.size() == 0){
            throw new Exception("请先配置本小区的名称");
        }else{
            map.put("area", allArea.get(0).getName());
        }
        // 通过楼号, 查出01 和02 不同朝向 的房间
        List<HouseSource> houseList = houseChooseService.listByBuildingNum(buildingNum);

        List<HouseChooseViewAdapter> leftList = new ArrayList<HouseChooseViewAdapter>();
        List<HouseChooseViewAdapter> rightList = new ArrayList<HouseChooseViewAdapter>();

        for (HouseSource h : houseList) {
            if (h.direction().equals(Constants.ROOM_NUMBER_DIRECTORY_LEFT)) {
                leftList.add(new HouseChooseViewAdapter(h));
            }else if (h.direction().equals(Constants.ROOM_NUMBER_DIRECTORY_RIGHT)) {
                rightList.add(new HouseChooseViewAdapter(h));
            }else{
                throw new Exception("该楼盘房间号格式错误,最后两位为 "+Constants.ROOM_NUMBER_DIRECTORY_LEFT
                        +" 或 "+Constants.ROOM_NUMBER_DIRECTORY_RIGHT+" 房间号:"+h.roomNum() + " 楼号:"+h.buildingNum());
            }
        }
        //房间号从大到小
        Collections.sort(leftList);
        Collections.sort(rightList);
        map.put("west", leftList);
        map.put("east", rightList);

    }
    return new ModelAndView("choose/choose", map);
}

[/code]

一个方法内部的代码应该建立在同一层次的逻辑抽象上。
[quote]
1. 从表单获取数据
2. 查询相应数据(具体的业务 一行代码搞定了)
3. 转化为 页面所需要的相关格式
4. 数据排序 并放到map里
[/quote]
按照楼主对代码的抽象,确实有很多是与业务无关的数据操作,这些代码放在controller中就会出现代码的冗余,[b]即使抽象成了1行工具方法也是冗余的[/b]。

我建议楼住考虑使用servlet中的[b]filter(过滤器机制)[/b],可以了解一下不但可以在servlet的service方法前进行处理,也可以在service之后进行处理(struts2等其他框架也有类似的技术)。

写函数就像是讲故事,讲每个故事看看能不能分段的讲,这就意味着分成几个小故事,然后再组合到一个故事内容中。像这种Controller的方式,小项目的话,直接写里面就行了,如果觉得乱,建议写一些Service来做。各有各的喜好!

request.getParameter是可以不写的,可以用@ModelAttribute直接把表单的值填充到对象里。
下面那一大段显然是业务逻辑,应该封装,比如用houseList拆分左右列表,就可以作为一个完整的独立方法。
不一定放service,你可以写些独立的工具类来放这些方法

是的,要想代码少你可以讲service封装到一个bean中,用map作为参数传递
spring mvc编程就是这个样子的应为你的controller是单例,虽然高效,但是牺牲了类继承

楼主还是讲讲这个代码的需求吧, Controller里写这么多东西实在不是什么雅观的东西, Controller最多做三件事,第一是从Request取数据,第二是传递数据给Service处理,最后一步是根据Service返回的数据,渲染相应页面,返回。

看你一会调Repository,一会调Service的

建议你去看看 重构 这本书,对你如何写出简单,高效,易懂的代码很有帮助,另外我不知道你的业务怎么样,但Controller里面多分几个private类型的方法总是没问题的,具体控制类,代码量会大大减少,阅读也更加清晰