新手的第一个工程的总结(第一次写文章,请前辈们指教)
napoleonn http://www.jdon.com Oct 1, 2004 3:42 PM 回复
孔子说:“学而不思则罔,思而不学则殆。”从我做项目的经历,我深深感叹古人闹腔邸?
去年我毕业设计时候做的一个项目是毕业设计治理系统。当时老师给我们的要求是用jsp 和 Javabean来实现。我主要负责项目建模和Javabean部分,后来负责数据库的同学被SARS困在家不能返校,所以数据库部分也由我来完成了。当时对java的知识是非常贫乏的,只有简单的语法基础,连JSP、 javabean都是第一次听到过。不知道从哪里开始,于是就研究老师给的一个非常简单的演示项目,首先觉得javabean是个比较简单的东西,于是就先开始分析用户需求。
需求怎么来描述呢?由于学校教育的局限,加上自己研究了很长时间高数,政治,英语(干什么用大家都明白吧),造成了知识的严重匮乏。我就以参加毕业设计人员为中心,建立他们的需求列表。但是这样的需求描述是非常片面的,几乎都是静态的需求,而且很难设计几个用户的交互过程,和某些状态的改变。而且这种需求是否真正符合需要是个问题,所以我马上和同学一起设计web界面,目的很简单,因为用户的需求都是通过界面来实现的,对界面的设计能涵盖最终提交用户的功能,而且还能发掘很多非用户的需求。这样我在实现这些功能的时候会有数。在一年后当我仔细看过用例分析,uml后感觉是如获至宝。心头的结全部打开。
建模该怎么建?当时真是什么概念都没有,虽然知道uml,但是仅仅知道皮毛。于是我就很简单的从对象的角度考虑问题,首先找毕业设计治理系统中涉及的人员,这个是很明显找出来的,涉及到学生,教师,治理员,进一步提取出项目对象,各个人员之间通讯的消息对象,毕业设计文档对象,等等。接下来设计数据库表,由于学校教数据库的时候只有讲述了ER图到关系模式的转化,而根本没有讲ODL到关系模式的转化(现在看来,ODL应该更好,对理解O/R Mapping有更多的帮助。)于是就画ER图,建立各种表,设定主键,外键,等等。
我碰到的首要问题就是学生,教师,治理员该怎么办,每一个对象建一个表,似乎也没有什么问题。但是在建立消息对象的时候就有问题了,因为消息是要在学生,教师,治理员任意两者都能传送的,我建消息表的时候是这样设计的:一个消息的内容,消息的发送人,消息的接收人(消息内容和发送人一个表,为解决冗余接收人单独一个表),这样这个消息就有很大的灵活程度了,消息发送人可以是三种角色间的随便一种,更进一步,这样的消息可以是系统生成的消息,而且接收者可以是随便哪种角色。但随之带来的问题是:消息发送人、接收者该去参照谁呢?显然填一个发送者、接收者的id是不够的,必须连发送者的角色也填上。第二种方法,每个角色有一个收到消息的列表,让它去参照单一的消息表id,这样也能解决问题。第三种方法,把学生,教师,治理员合并成一个用户表,那么消息发送人,接收人只要简单的参照一个通用的用户id了。这种合并子类的方法会造成教师,治理员的行有些null值,但是考虑到教师和治理员的数目远远小于学生的数目,所以这样的冗余是忽略不计的。最后我还是选择了最后一种方法。不过我还是觉的是对象模型向关系模型的一种妥协。
接着我着手设计javabean,访问数据库用的是单纯的JDBC。因为我对前台界面要访问一个对象的哪些属性是不了解的,事实上也不该了解。所以我只能从数据库取出一个完整的对象,让他来决定究竟要访问哪些属性。而且对对象的修改也是这样,前台修改好新的对象的属性,我来进行更数据库的同步。于是我的javabean就出现了这样的方法:load()、 store()、 update()、delete()这样的对象和数据库表同步的方法。这在一年后的今天看来,实际上我已经自己做了一个O/R Mapping的工作了。当时自己做这样的O/R Mapping是相当痛苦的事情,而且用的方法也是最粗浅的,就是整个对象更数据库同步,即使没有修改的属性也同步,所以要同步的话,必须要先把对象从数据库取出来,修改后再写回。而且要求所有属性必须是nullable的non-primitive类型。第二个问题,对表中的外键怎么反应到bean中?比如每个学生有一个辅导教师,在数据库中很明显学生表需要一个外键参照教师id,但是在StudentBean中教师属性是写Teacher对象呢,还是Teacher id值呢,按照面向对象,很明显应该Teacher对象,但是我就觉得这是个多么heavy的事情呀!再想想教师情况,一个教师有一个Collection的Student对象是多么“重”!意味着load一个教师要load所有的students。于是我采用的方法是:还是用对象,比如teacher 的学生属性,还是一个collection Student对象,同时提供了一个loadStudents()的方法,load teacher对象的时候并不load 学生属性,只有bean的用户显式调用loadStudents()的时候才会加载一组student对象,这在现在看来似乎我自觉不自觉的实现了lazy loading?
现在审阅当时编写的javabean,犯的最大最大的错误就是把data Access object和business workflow混在一起了。比如把教师所有要调用的功能都放在教师对象里面,而有些功能有时是要涉及几个bean的。现在看了简直是惨不忍睹的设计,虽然当时也困惑过,但是却没有动动脑筋来解决,我现在看了session bean 的思路时,觉得是那么的愉快、自然。
当时困惑的还有关于JSP的处理,JSP只是负责显示的,但是为什么一个JSP提交的数据要给另外一个JSP去处理呢?这是很不愉快的做法,于是有了最初的servlet做控制器的想法,但是当时顾不了研究那么多,也没有最终实现,究竟前台不是我负责的。当我现在知道了StrUCts,MVC Model2的时候,我以前的困惑都随之解决。又一次感觉非常愉快。