OO2019第四次作业总结

第四单元作业两次架构设计

第一次作业

本次作业中,我们的任务是对UML类图的结构进行梳理分析,将从json文件中解析出来的UML图中的元素建立层级关系,并且基于给定类图完成一些基本的查询任务。

本次作业中我将UmlClass,UMLInterface和UMLOperation类进行二次封装得到了相应的MyClass、MyInterface和MyOperation类,因为在MyClass类中存储中该类继承的父类、直接关联的类和实现的操作等信息,通过类和类成员将UML类图中的元素建立关系。

出于上述设计,建立关系的过程实现为对零散的UML元素进行遍历,识别其中的类和接口存储在顶层;再对剩余元素中的继承关系、关联关系和方法等第二层UML元素进行识别并在第一层中识别出来的类和接口中建立这些关系;最后对方法参数进行遍历,将其添加至其所对应的方法中,完成对UML类图中各元素关系的构建。

至于类实现的接口、类的关联和类的方法等查询在建立了上述类图中元素之间的关系后,通过对MyClass等新封装的类中成员变量进行计算即可得到,并且为了提高效率,在计算得到结果后将其使用成员变量进行存储,以提高查询效率。

第二次作业

第二次作业在第一次作业的基础上添加了顺序图和状态图,以及类图相关规则的检查。对于顺序图和状态图中元素关系的构建和查询,我们采取了和第一次作业相同的策略,将需要存储数据信息的类UMLInteraction和UMLStateMachine进行了封装,并在遍历元素的过程中建立顺序图和状态图元素关系,通过类中成员变量进行相关计算。

对于Rule002的查询,我在MyClass类和它的Attribute和Association建立联系的过程中对命名重复进行了统计,由此完成Rule002的查询。

对于Rule008的查询,我在抽象了一个图类,通过tarjan算法检查有向图中是否有环;对于Rule009的查询,同样在图类中使用带记忆的DFS算法检查两个点之间是否存在多条路径。

四次作业中架构设计以及OO方法

第一单元作业中的任务是表达式计算,虽然是第一单元作业,但是综合性已经比较强了,将面向对象中的最基本的概念封装、继承和多态都有所应用,通过类的封装,我们可以将相关联的数据和相关方法封装到一个类中,以实现模块化,通过父类的继承可以很大程度上提高代码的复用率,通过不同的类实现相同的接口,可以实现动态方法调用;除此之外,我还学到了面向对象中的组合模式、访问者模式和工厂模式等常见的设计模式,并在几次作业的实践中体验到了使用面向对象的设计模式相比此前面向过程的流程式代码带来的可拓展性和易维护性。

第二单元作业中的任务是通过Java多线程机制对多部电梯的模拟,这次作业在正确性的基础之上又对程序的安全性提出了要求,我们需要选择合理的程序的架构以更大程度上确保多线程协作的过程中不会出现预期之外的行为,我们可以选择使用Java库中线程安全类、使用synchronize关键词保护共享变量等方法避免线程之间的冲突,同时单例模式和观察者模式也在架构设计方面提供了帮助,通过这次作业,我们了解到一个好的面向对象架构也有助于支持程序的安全性。

第三单元作业围绕JML规格展开,三次作业层层递进,让我们充分认识到了好的架构对于可拓展性的意义,通过学习JML语言,我们可以形式化的表达Java执行程序的期望,JML语言是更高层次上的架构设计,更加具有抽象性,因此在编程的过程中,先对各个模块的功能进行JML层次上的行为功能进行梳理,可以有助于后续过程中代码实现的有效性和正确性。同时JML也是检查程序实现是否正确的一种方式,通过z3、cvc4等SMT solver可以对程序是否满足期望进行验证。

第四单元作业中我们学习了UML语言,是一种更为抽象的建模语言,通过类图、顺序图和状态图来描述任务求解的方法,这一层次上的设计相比于程序实现更为抽象,并且相比JML语言更加直观地表示了任务的求解方法,也有助于对程序的正确性进行检验。通过编写Java程序分析UML模型,我们更好地了解了UML模型中各个元素之间的关联以及模型的有效性。

测试理解与实践

第一单元作业中我使用了JUnit进行测试,测试过程比较理想,通过将测试样例分组以检查化简、求导等各个功能的正确性,并且通过自动化测试极大地提高了测试效率。

第二单元作业中由于电梯是实时动态的,因此测试起来相对复杂,并且由于多线程程序的不确定性,很难确保输出结果的稳定性,考虑到mutable variable是程序bug的万恶之源,我着重对可变变量的状态进行了观察和测试,除此之外,这一单元作业中并没有进行复杂的测试,这可能也是导致强测失分的原因。高效对多线程程序进行测试始终是一个难题,这方面还有很多技巧可以学习。

第三单元作业中同样使用了JUnit进行测试,这次作业中,在JML语言规格的帮助下可以逐条编写测试样例对程序的正确性进行检查,从而提高测试的全面性。遗憾的是这次作业似乎更看中程序的执行效率,因此我强测中不少测试点没过,因此在测试过程中对程序性能加以考虑也是格外重要的。

第四单元作业的测试我也只是对容易出问题的地方构造了测试样例去检查,并没有使用一些高效的测试手段。可以说我在测试这方面的能力还十分匮乏,以后还需要多加锻炼。不过相比于测试,我更加信赖形式化验证,因此后续学习过程中,我会更加侧重函数式编程和形式验证领域的工作。

课程收获

收获非常多。

对Java语言的使用。这部分主要是大量的代码训练和反复阅读修改代码让我对Java这门语言更加熟悉。

面向对象的设计模式。面向对象在带来好处同时自然也带来了一定的局限性,通过合理使用面向对象设计模式可以更大程度上提升代码的简洁性和正确性。

多线程程序的理解。在现代程序系统中,并发处理程序尤为常见,通过电梯模块的训练,我了解到了更多线程安全程序设计上的原则与具体实现上的技巧。

UML和JML等抽象语言。相比于具体的Java代码,这些抽象的设计都是更高阶的内容,能从更抽象的层次有效地解决问题,再写出来的代码一定不会差。

课程改进相关建议

三点建议如下(我是高工学生):

实验课改成学生和老师或助教以组为单位讨论设计和代码实现的细节。首先,实验课内容我觉得非常无聊并且没有必要,我感觉课上测试仿佛就是老师不信任学生能够独立完成课下作业而设置的关卡,但是每次课上测试后什么反馈都没有,让我非常失望,不如利用这个时间去反复去打磨课下作业的代码,老师经常说即使过了强测依然存在各种bug,感觉只是说说而已,这就很奇怪了,不如利用实验课这个机会深究一下。

JML语言和课下作业关系不是很紧密。根据我周围同学的反馈,第三单元的第三次作业和JML基本没有什么关系,而且侧重点是算法实现性能,不如改成一些关于JML语言的验证,可以考虑KeY验证工具,可参考KeY验证工具对JDK开源库中Timsort算法的验证工作,当然OO课程中可以考虑一些简单的程序进行验证。

第一次博客作业我看到了课程组的反馈,后面就没有了,虽然读全部同学的博客实在是多,但是这么优秀的OO课程组一定有办法解决好的对不对。

Happy OO, Happy Hacking!

猜你喜欢

转载自www.cnblogs.com/huluobo7161/p/11076405.html