发帖    主题    评论    推荐    标签    作者    订阅    查搜    注册   登陆   关注
 
面向对象 设计模式 领域驱动设计 企业架构 框架 开发教程 微服务 大数据 扩展性 并发编程 事件驱动 分布式 SOA

banq大哥、各位好心的大哥大姐们!求教一个关于Sturts+Spring中ActionForm的问题

2007-08-04 10:08
赞助商链接

在一次很偶然的,也忘记是什么时候的事,找到了J道这个网站,被这里的讨论的问题深深的吸引,于是养成了每天都会到J道来逛逛,总会有不少收获,也是通过这个网站知道了什么叫DDD,深入了解了OO思想,对我实在是非常大的帮助(正在朝这方面拼命努力加油ing),非常佩服banq大哥的渊博知识和热心为道友门解决很多困惑、为中国软件业的发展孜孜不倦的贡献的精神!!!!

经常看别人的提问和热心道友们的热情参与,受益非浅,今天终于有机会向banq大哥和热心的道友们请教了,希望大哥们指点小弟一下!

我遇到的问题是这样的:在一个main.jsp页面上点击一个链接
<a href="addStudent_listClasses.do">新生注册</a>后,跳转到学生注册的addStu.jsp页面上,该页面中的注册表单中有一个要学生选择班级的下拉框

<html:select property="classesNo">
  <html:option value="0">请选择班级</html:option>
  <html:options property="value" labelProperty="label"               collection="classOptions" />
</html:select>
而我的目标是:当跳转到学生注册这个页面时,班级下拉框里供选择的班级信息是从数据库的班级表中读取的而不是在JSP页面上写死的,根据自己对Struts机制的理解,我于是采用下面的做法:
1、<a href="addStudent_listClasses.do">中的addStudent_listClasses.do对应的Action的作用是用来在跳转到学生注册页面之前先获得ActionForm的一个实例,并显式调用ActionForm的reset()方法来初始化学生注册页面下拉框中的内容,而这个Action中我是通过Spring把ActionForm注入的,代码如下:
public class AddStudent_listClassesAction extends Action {
private ActionForm addStudentForm = null;

public void setAddStudentForm(ActionForm addStudentForm) {
this.addStudentForm = addStudentForm;
}

public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
addStudentForm.reset(mapping, request);
request.getSession().setAttribute("addStudentForm", addStudentForm);
return mapping.findForward("showAddStudentPage");
}
}
2、我在学生注册页面对应的那个ActionForm的reset()方法中这样写:
public class AddStudentForm extends ActionForm {
// 省略其它属性和setter、getter方法
private Integer classesNo;
 // 通过Spring注入
private IClassesService classService = null;

public void setClassService(IClassesService classService) {
this.classService = classService;
}

......

public void reset(ActionMapping mapping, HttpServletRequest request) {
// 从数据库的classes表中读取数据设置 班级 下拉列表供选择
ArrayList classOptions = newArrayList();
Classes classes = null;
  // 通过IClassesService接口调用相应DAO中的方法查出所有的班级信息
List<Classes> list=classService.queryAll();
Iterator i=list.iterator();
while(i.hasNext()){
classes=(Classes)i.next();
LabelValueBean option = new LabelValueBean(classes.getClassesName(),classes.getClassesNo().toString());
classOptions.add(option);
 }
  request.setAttribute("classOptions", classOptions);
  }
}
这样做是达到了功能的实现,可是老师最后说这样的做法不太好,原因大概是这样说的:
没见过在Action里面注入ActionForm的,不是传统的做法(我学Java没几个月也不太清楚,banq大哥是这样的吗?),没有经过实践验证,不知道是否会有潜在的问题。

而老师推荐了如下的做法:

在<a href="addStudent_listClasses.do">中的addStudent_listClasses.do对应的Action中不注入ActionForm,而只是在Action中把addStu.jsp中下拉框<html:options property="value" labelProperty="label"               collection="classOptions" />中需要的collection的数据准备好,存到request范围中,也就是把原来我在ActionForm中的reset()做的事搬到这个跳转的Action中来做,代码如下:
public class AddStudent_listClassesAction extends Action {
// 通过Spring注入
private IClassesService classService = null;

public void setClassService(IClassesService classService) {
this.classService = classService;
}

public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
  // 从数据库的classes表中读取数据设置 班级 下拉列表供选择
ArrayList classOptions = newArrayList();
Classes classes = null;
  // 通过IClassesService接口调用相应DAO中的方法查出所有的班级信息
List<Classes> list=classService.queryAll();
Iterator i=list.iterator();
while(i.hasNext()){
classes=(Classes)i.next();
LabelValueBean option = new LabelValueBean(classes.getClassesName(),classes.getClassesNo().toString());
classOptions.add(option);
 }
  request.setAttribute("classOptions", classOptions);
  return mapping.findForward("showAddStudentPage");
}

上面说的两种做法都是可以达到目的的,我的疑惑是:]用哪一种方法好?好在什么地方?不好的做法不好在什么地方?希望banq大哥能抽空帮我解释一下,感激不尽!!!!

但是我觉得注册页面的表单里的数据应该是由ActionForm来提供的,像我的老师这样把表单的数据通过其它的途径提供,有没有破坏Struts的什么结构或是什么的?(我也不太清楚,但总觉得怪怪的,请老大指教!)

[该贴被yame83215于2007年08月04日 10:12修改过]
[该贴被yame83215于2007年08月04日 10:14修改过]

2007-08-04 12:48

动词和名词分离原则。这是Java目前一个基本原则。

ActionForm是一个名词;Action是动词;
将动作功能放入Action,将数据字段放入ActionForm。

好处很多:便于维护等。

2007-08-04 13:31

能不能讲解清楚点啊?
在我的这个例子中初始化下拉框中的内容是属于数据字段?还是属于动作功能??
我说的那两种做法哪一种才是符合Java基本原则的?

如果把ActionForm里的reset()方法里的操作搬到Action里是符合动词和名词分离原则的话,那么ActionForm里的reset()到底能做些什么呢?reset()不是执行一些初始化的工作的吗?(个人的理解,有误请更正),这算不算是动作功能?但它为什么被放在ActionForm这个名词里?Struts设计的目的是什么?

至于可维护性,扩展性等方面,我觉得第一种做法好像更优一些,当改用其它实现方式(不用Spring时)可以直接把通过Spring注入的service改用其它途径获得(或是采用new的方式),在修改的代码量上两种方法差不多,但我觉得第一种好像更好的保存了Struts结构的完整性????

2007-08-05 09:55

ActionForm的reset是对自己对象的字段进行复位的方法。是一些轻量方法,换句话说是小动作,而你现在加入了包含后台数据库操作等重量操作方法,这些属于重要的动作了,这些应该尽量放在execute这个主要方法中。

主要出于良好编程习惯,尽量将和后台发生耦合的代码都放在一起,这样以后后台发生变化,别人维护修改你的代码就方便,否则,RESET里有后台代码,execute也会有,多处修改就容易出错。

如果出于功能需求,必须放在reset中,也需要重构一下,不能将这些代码全部写到reset一个方法中,而是重建立一个方法或包装你这些涉及后台操作的代码。


[该贴被banq于2007年08月05日 10:10修改过]

2007-08-05 19:19

明白了,这样子解释一下清晰了,谢谢哦

赞助商链接

赞助商链接

返回顶部

移动版 关于本站 使用帮助 联系管理员 最佳分辨率1366x768
OpenSource JIVEJDON Powered by JdonFramework Code © 2002-20 jdon.com