(1)前言:
面向对象程序设计(java)是一种区别于c语言的设计语言,其最大的区别便是c语言为面向过程,逻辑为线性逻辑,而java将所要进行的操作分散到各个类当中去,分别完成某项任务,直观的讲便是,c语言是一条简单的流水线,这条流水线上便可完成所有内容,故为线性逻辑,而java则是一座大型工厂,里面有不同的部门专门负责不同的事情,最后一起完成工作,这也是java编程的核心准则之一--单一职责原则,而大作业则是对java的不断熟悉认识的过程。
第一次大作业主要是熟悉面向对象语言设计,初步感受此种编程语言的编程特点与形式,内容偏向基础性的知识,例如对类的初步运用,利用类来处理数据信息。
第二次大作业难度递增,在实现类的运用的基础上追加了Arrylist,Linkedlist,HushMap的使用,使对数据的处理更加有条理。
第三次大作业难度再次递增,主要考察类间关系的处理。
三次大作业均对正则表达式有一定的应用,熟练掌握后可简化代码。
三次作业难度依次递增,题量适中,均为二至三道小题与一道大题的模式,大题代码在数百行左右。
(2)设计与分析:
第一次大作业:
设计三个类“题目(Question)”;“试卷(Page)”;“答案(Anser)”
题目类:
此类中设计了属性 题目编号(num),题目内容(que),标准答案(standardanser)。分别设计了他们的getter方法来获取数据。设计test方法来检验输入答卷答案是否与标准答案相匹配。
试卷类:
此类中设计了属性 试卷编号(num),题目内容(questions)。设计了试卷编号的getter方法
答卷类:
此类中设计了属性 试卷(P),答案内容(ansers),答案结果正确性(result),可通过试卷来找到相应题目,并进行答案比对操作。
从题意来看,此次大作业只有较为简单的输入输出,故类设计较为简单,按照题目所建议三个类足矣,题目类保存题目数据,答卷类保存答卷数据,试卷类保存试卷数据。因为标准答案及题号都在题目类当中,故在题目类中设计判题方法来判断输入答案正确性,并将判断结果存入答卷类中。
此次作业中对于类的关系调用考察较少,内容较为基础,我将输入的数据在Main类进行处理后再存入相应的类对象中,利用题目(Question)类中的test方法对答卷中的答案进行判定对错,存入答卷类中的result中,再由Main中的输出方法进行输出最后得出结果。第一次大作业中数据输入结果输出都较为单一简单,故即使在主Main类中完成方法设计也较为简单,但此种设计在后续输出输入格式要求增多,判定增多的模式中则弊端就很明显,后文第二三次作业详述。
第二次大作业:
设计类与第一次大作业大差不差 “题目(Question)”;“试卷(Page)”;“答案(Anser)”
题目类:
此类中设计了属性 题目编号(num),题目内容(que),标准答案(standardanser)。分别设计了他们的getter方法来获取数据。设计test方法来检验输入答卷答案是否与标准答案相匹配。
试卷类:
此类中设计了属性 试卷编号(num),题目分值(que_score),设置了num的getter方法及总分计算方法sumScore,用于判定卷子总分是否为满分100.
答卷类:
此类中设计了属性 试卷(P),答案内容(ansers),答案结果正确性(result),可通过试卷来找到相应题目,并进行答案比对操作。
此次作业相比第一次,多了试卷信息的输入及判定,要求对试卷总分进行判断,故类设计与第一次作业无太大差异,需在试卷类中获取题目分值信息并计算其总分,故定义sumScore方法,用于计算总分利于最后结果输出,在输入时,会出现输出多张答卷的情况,在输入时需增加判定。因为时间原因我采用了和第一次作业差不多的设计思路,将输出放在了Main中,但这也代表了要运用复杂的逻辑关系来进行输出操作,如题目要求若答案数量少于题目数量需输出“anser is null”,但在主函数中难以计算答案数量,故这项输出难以实现,且难以实现的不止这一条,题目给的输入中含多张试卷输入,在主函数中难以设计合适的循环终点来实现多次分数输出,且最后输出也容易造成非零返回的问题报错,此次作业提醒我应当要严格按照单一职责原则来对类进行合理的设计,减少Main中方法数量,将其作为调度中心而非操作中心。
第三次大作业:
设计类“题目(Question)”;“试卷(Page)”;“答案(Anser)”;“答卷(Anserpage)”;“学生(Student)”
题目类:
此类中设计了属性 题目编号(questionnum),题目内容(content),标准答案(standanser),题目存在性(mode)。并设计了他们的getter方法。同时还有testanser方法来检验答案正确性
试卷类:
此类中设计了属性 题目编号(pagenum),题目分值(que_num)。设计了编号的getter方法,总分计算方法(sumScore),获取单题分数方法(score)。
答案类:
此类中设计了属性 答案内容(anser),题目序号(num),题目分值(score),答案正确性(test)及它们的getter方法。
答卷类:
此类中设计了属性 试卷编号(ansernum),学生学号(studentid),题目序号(sumget)及它们的getter方法。
学生类:
此类中设计了属性 学生学号(id),学生名字(name)及它们的getter方法。
第三次大作业难度开始变得较大,输入增多,错误判断增多,输出内容增多,故我设计的类也增加了,题目中多给了一项学生类信息,因此也多增加了一个题目类,由于题目中会出现删题目的情况,因此需要给题目类新增属性存在性(test),同时题目有要求判断输入格式问题,因此会用到多种正则表达式匹配模版,这是一大难点,因为不同信息输入格式不同,判断标准也就不同。在输出时,我依然将其放在Main类中输出,而后果与第二次大作业相同,输出困难,碰到相对***钻的输入则无法正常输出,且若因为格式问题而导致某一类中无信息输入,则无法进入后续循环,造成输出结果为空的问题,需要额外设置无用数据进入循环,但这样治标不治本,应当从根本解决,将输出判定放于某一特定类中来完成,尤其完成相应数据调动,最后再由Main来进行最终调度。
(3)踩坑心得:
三次题目集共同问题-正则表达式的使用,由于对正则表达式使用较少,对其匹配模式不熟练,多次因为正则表达式匹配出错导致数据难以获取,后续步骤难以进行
如:题目要求匹配格式" #X:"+学号+" "+姓名+"-"+学号+" "+姓名....+"-"+学号+" "+姓名 ”
String pattern2 = "#X:\d+\s+\w+";
采用此种匹配模式只会匹配第一次格式数据,而“-”后的内容则无法匹配,导致数据丢失,程序运行出错。、
在代码实现中还碰到些低级语法错误,如if语句判断相等使用“=”而不是“==”,循环未设置终点或终点设置出粗导致程序非零返回。
在编码过程中最容易错误处理的地方--类间数据调用,由于不同类间调用数据频繁且变量名称大多相同,在后段编码过程中容易无法准确找到所用变量,耽误时间,同时类间关系也设置较为复杂,未提前预想好,导致编码时时常因为类间关系而卡住,且容易出现调用的类为空的情况。
如:题目中题目信息及答卷信息都含“答案”这一数据,在代码实现过程中难以区分,应当添加适当注释便于理解。
(4)改进建议:
在作业中并未完全实现面向对象设计理念,部分操作如利用正则表达式匹配获取数据及数据的输出操作任然是在Main类中实现,显得过于冗杂,后续可新增两个类分别单独实现数据的获取及输出操作,对于后续如果要更改输入输出格式也更加便利。
在编码前未对所用类进行预先设计,都是边写边想,所以导致类间关系难以弄清楚,难以区分,后续可利用画图工具或者纸上画图重新设计类间关系并理清其中关系,对于以后的作业也更加方便,利于修改。
(5)总结:
此三次作业为java的起点,而三次作业中我只有第一次拿到了满分,而第二次的最后一道大题甚至只得到了7分虽然极大部原因归咎于时间安排,将任务堆在最后一天完成,但这都是老师再三提醒过后我任犯下的错误,所以应当归咎于我自身。
此三次作业主要锻炼了我的java基础编码能力,正则表达式,各种集合类的应用及类间关系的处理。
从题目而言,这三次题目设计难度虽然逐步递增,但跨度不大,但我个人在编码中,还是难以舍弃c语言的编程习惯,认为类只是用于储存数据的某种类型,并未完全实现面向对象设计,而再第二三次作业后,这种编程方式的漏洞也完全显现出来,因此在之后的作业内容当中,我会更加偏向于面向对象设计,并严格遵守单一职责原则。