以下这段代码为例。。。
里面包含了几部分:
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类型的方法总是没问题的,具体控制类,代码量会大大减少,阅读也更加清晰