一、第四单元作业架构设计
第一次作业(类图解析)
第一次作业对类图进行解析,一共需要完成10个查询指令,包括对类的个数,类中属性、方法的个数,类实现接口的个数等内容的查询,特别需要注意的是各种继承的情况。为了能够方便地实现所有功能,需要一个良好的架构保存相关信息的同时体现出继承和关联关系。
我建立了MyClass
和MyInterface
两个类作为并列的层次,还建立了MyOperation
类,作为MyClass
类的下一个层次。在所有的UmlElement输入时,在MyUmlInteraction
类的构造方法中,分三步初始化结构层次:先提取出UmlClass和UmlInterface,分别存入Hashmap中;再提取出UmlAttribute、UmlOperation、UmlGeneralization、UmlInterfaceRealization、UmlAssociation和UmlAssociationEnd按照它们的parent_id找到对应的类;最后提取UmlParameter,找到对应的方法。层次关系就建立好了。
查询类中的属性有多少个等指令需要包含所有父类的属性,采用循环找父类,直到没有父类的方法。
while (fatherId != null) { fatherClass = classes.get(fatherId); count += fatherClass.getAttrCount(); fatherId = fatherClass.getFatherId(); }
对于查询类实现的全部接口,无论是直接实现还是通过父类或者接口继承等方式间接实现,都算做实现了接口,接口可能多继承,所以应该先找到该类通过类继承的所有接口,然后通过bfs的方法找到所有接口通过接口继承的所有接口,注意不重不漏。
idList.addAll(thisClass.getInterList()); while (thisClass.hasFather()) { thisClass = classes.get(thisClass.getFatherId()); idList.addAll(thisClass.getInterList()); } //找到所有父子类的interfaceId,存在idList里面,类可能实现多个接口 //下面找这些interface的父接口,每个接口可能有多个爸爸 //所有id入队 for (String id : idList) { queue.add(id); } while (!queue.isEmpty()) { String thisId = queue.poll(); idListPro.add(thisId);//加到最终id set里面 MyInterface thisInterface = interfaces.get(thisId); if (thisInterface.hasFather()) { Listfathers = thisInterface.getFatherIds(); //对于每一个父亲,如果是接口,加入队列 for (String id:fathers) { if (interfaces.containsKey(id)) { if (!visited.contains(id)) { visited.add(id); queue.add(id); } } } } }
第二次作业(时序图、状态图解析、模型有效性检查)
第二次作业对时序图和状态图的解析不太复杂,对三种图架构清楚即可。我采用了不同的package来处理不同的图。在MyUmlGeneralInteraction
类中实例化三种图的interaction类,然后在其构造方法中把不同图的元素分别传入不同的interaction对象中,然后再分别处理。
对于模型有效性检查,第二个和第三个比较复杂,第二个是要判断是否有循环继承,第三个是要判断是否有重复继承。我在判断循环继承的部分出现了bug,只是单纯的通过循环找父类,看父类是否与该类相等,但是当查询的类的父类在循环继承的圈中时,会出现死循环。情况没有考虑周全,导致出现bug。接口可能会多继承,所以通过bfs从一个接口出发找环。第三个模型有效性检查看一个类的所有父类实现的接口和接口的父接口有没有重复,可以借鉴查询类实现接口的方法。
二、四个单元架构设计及OO方法理解的演进
这一学期通过四个单元的训练,对面向对象方法有了从无到有的认识,架构设计也越来越熟练清晰。
最开始的第一单元是java入门,也是面向对象入门,了解了什么是对象,基本的语法和继承多态的内容。因为是入门阶段,所以花费了大量时间处理多项式求导的各个细节,但是也为后面打下了良好的基础。
第二单元电梯设计是传说中的oo高潮阶段,学习了十分重要的多线程。从第一次的傻瓜调度电梯到第三次的多部智能电梯,每次完成都十分有成就感。通过这个单元的训练,掌握了面向对象的一大重要功能,也用面向对象解决了一类实际的问题,比较接近以后的软件工程,也对面向对象有了更加清晰的认识。
第三单元学习JML规格语言,是从未接触过的,实现了规格和代码之间的互相转化,也了解了junit单元测试方法。学习规格有助于我们设计架构时更为规范,明确每一段代码的功能,也为后续测试提供了便利。
第四单元学习UML,不仅学会了画和分析各种图,还通过自己实现模型解析器了解了各个UmElement的层次关系。在这个单元中,看起来代码作业不是十分难,但是恰恰需要良好的架构才能完成,这时前几单元的训练成果就派上了用场,可以比较轻松地构建出合理的架构。
三、四个单元测试理解与实践的演进
测试是程序设计很重要的一个部分。从最初认为测试只是构建几个测试点验证程序正确性,到覆盖性测试,到测试引导代码实现,到后来接触到单元测试,我对测试的理解逐步加深。测试不仅仅是一个孤立的部分,测试十分重要,也有许多方法。在实现代码之前就需要考虑测试的问题,这样才可以将一些bug扼杀在萌芽之中。规格语言也是为了方便测试,按照规格写代码是良好的习惯,也可以使实现单元测试成为可能,而单元测试往往才是最可靠的测试。
在今后的学习过程中,应该重视测试,也应该不断探索测试的手段,使自己的程序无bug。
四、课程收获总结
这一学期下来,可以说,OO是一门好课,它带给我:
-
面向对象基本方法和应用
-
熟练使用Java语言编程
-
实现1000+行代码的工程能力
-
了解多线程相关知识
-
了解规格语言、单元测试
-
了解UML统一建模语言
-
模块化编程的能力
-
日益良好的代码架构
五、课程改进建议
- 希望课程组可以对指导书的要求和细节及早完善,尤其是边界情况,对一些容易混淆不清的问题能有更清晰的说明。
- 希望对于强测中容易超时的压力测试点在中测中可以给出运行时间。
- 希望对复杂的问题过后可以给出一些讲解和合理架构的介绍。
最后感谢老师和助教们一学期的辛苦付出~