UML系列——OO Unit4分析和学期总结

一、本单元的架构设计

 1.类图

第一次

第二次

2.关键方法和架构简述

   总体而言是读取图的时候就完成大部分计算(完成缓存),调用查询方法时只是展示计算的结果,少部分直接计算。主要是设计了各种自己定义的类,处理输入数据时完成各种类的创造和放入容器。第二次作业中,使用预处理器对输入的UML元素进行了多次遍历,先创建具体的对象,再创建次级的从属对象,再读取关系而调用之前创造的对象的特定方法,从而实现把输入的信息重新组合,以便于符合要求地查询。因而各功能是单元化的,对开发和测试比较有利。

二、架构设计和OO方法理解演进

  第一单元时,对架构方面的思考不是很深入,仅仅是做到从任务要求中提取出不同的对象,并考虑它们之间的消息传递。这是我最开始对面向对象方法的理解。当时建立对象和类只是考虑到能实现功能即可,认为这是写程序的一种不同的、更直观易懂的方法。但完全没有考虑到代码的安全性、分工的明确性、可扩展性和复用性。从第三次作业中,明显感受到代码几乎是完全重构的,耗费了大量时间,从而开始不仅仅考虑实现功能,而更加考虑是否能更好地支持更多功能,是否能走得长远。

  第二单元是在多线程编程的视角下进一步加深对面向对象方法的理解。在本单元中,我体会到对可扩展性、复用性的取舍和衡量。在某些地方可以保留较高的可扩展性,因为有很大的扩展可能,例如前两次中势必要考虑多部电梯,这在现实中非常的常见。而第三次中,特定楼层的电梯就不需要设计地非常具有可扩展性,因为特定楼层的电梯与建筑功能紧密相关,并不是非常常见的,因此专门设计调度规则和方案比较好,不必费力写出非常普适的调度方法。

  第三单元中由于我的实现方法是在输入时计算,查询功能只是输出计算的结果,因此需要注意数据的安全性。即查询的时候应该不改变任何存储的数据,或者计算某一个数值时不应该改变其他的数值;我主要使用的方法是Floyd算法以及其变体,于是在架构设计层面使用了工厂模式来实现,使得代码拥有较为安全的可扩展性。因而在实现一种查询任务之后,其他的查询都是类似的,编写起来十分轻松。但本单元中,需要注意的是,无论是JML的使用还是面对对象方法的使用,虽然保证了正确性,但是未考虑到算法的时间复杂度和空间复杂度,这一点需要单独考虑和处理。

  第四单元中,面对稍大的工程量,我主要按照功能进行封装,并增加了自己的类结合继承和接口来实现特定对象的搜索功能,从而快速处理数据。本单元中,我主要把任务分解为输入、检查和查询三部分,分别调用实现相应功能的专门类对输入进行处理,从而使开发单元化。

  总体而言,经过一学期的学习,我对架构的思考、面向对象编程的方法,有了质的飞越。

三、测试理解和实践演进

  最开始的时候,对测试的理解以及测试数据、测试方法、调试方式比较简单和单一。最开始认为只要程序运行的过程中不出现bug就是测试的目的(面向评测机的DEBUG),构造的测试数据以边界条件为主,使用的测试方法只是run或者辅以printf的调试方法。

  通过第一单元后,开始编写数据生成器、对拍器等方法来创造测试数据,并开始使用JUnit进行单元测试,使得测试模块化,减少了测试使用的时间。同时开始使用条件断点、分级测试的理念进行调试,并开始关注代码的覆盖率等,更好地利用其调试的信息,从而使得出现bug后定位到错误代码的时间大大减少,提高了测试的效率和质量。

第二单元时,学习了多线程编程时不同的测试方法,不仅了解到多线程的断点使用,也体会到了不可复现性对测试带来的挑战和不安全性的引入。

  第三单元是,接触到JML,体会到规范化对代码分工和测试带来的便利和好处,同时本单元开始考虑时间复杂度,不仅仅在功能上进行测试,也要考虑使用算法的时间和空间性能。测试数据的编写更加全面化,分别有覆盖多功能的数据、针对不同实现方法的最差情况最高时间复杂度的极端数据和空间复杂度较高的数据(本单元中对空间复杂度的限制较低,因而没有特别的关注)。

  第四单元明显感受到测试数据编写的麻烦,没有详细设计实现一个较为方便的测试数据生成系统,主要靠徒手造,这使得测试数据的完整覆盖与否完全体现在是否充分理解指导书上。本单元更多的收获是在理解用户需求的层次上。

  总体而言,我的编程的总体思路、测试数据构造、测试的方法、调试的方法等方面经过一个学期的学习都得到了非常大的完善和进步。

四、课程收获

  首先是对面向对象编程和JAVA语言有了更深刻更全面的理解。在大二上学期时,我也选择了JAVA课程并得以自学和自行摸索,通过这一学期的学习对我自己构建的知识系统有了比较好的修正和补全。现在回过头来看大二上学期时写的大作业(一个多线程的游戏),发现从类属性的隐藏、线程安全性等小问题到代码整体的架构、耦合度、圈复杂度等等来看都漏洞百出、“不忍直视”。

  简单分析,当时写程序时考虑问题简单,没有考虑到安全性、代码可维护性、代码可扩展性,测试也不够充分。经过一学期的学习之后,首先在写程序的时候增加了提前架构思考和完成后测试调试的过程,而不仅仅把大部分时间放在写代码上;在写属性或者创造新对象时,现在会注意隐藏和使用创造模式,来增加封装和安全性,这使得多人分工合作或者自己一段时间后再来编写代码的时候不至于不小心修改了不应该修改的部分从而引入错误。原先代码比较冗长,耦合度高,分类的逻辑更像目前folder的逻辑,或者仅仅是太长了所以分出来一些,没有考虑到业务逻辑,也没有考虑到可扩展性、代码重用等角度。目前会在编写类的时候更多考虑奥卡姆剃刀法则,同时使用继承、接口来增加代码复用。多线程编程中,了解了比较经典的生产者-消费者模型,包括在OS课程上所学的哲学家进餐、银行家算法等,对线程的安全性、死锁有了更好的理解,大大降低了多线程中出现BUG的可能性。以及对于代码风格的重视,使得起类名等更加简洁清晰,同时方法行数太多是就会自觉思考是否架构方面可以更优,以及访问是否可以是package可访问、是否可以使private的来提高安全性。我感受到遵守代码风格不是一件麻烦和多余的事情,而的确会提高代码的可阅读性、清晰性和架构的合理性。

五、关于课程的建议

1.强测部分中,某些次作业建议考虑功能和性能分别测评。如果使用较为复杂的优化方法,有可能会导致引入潜在的错误或者CPU超时等,虽然这是学生需要注意的地方,但是对大多数学生而言,往往会为了求稳而完全放弃优化,积极性得不到鼓励。

2.目前课程网站已经有非常好的功能,但吹毛求疵来说,有些易用性方面上的不足,具体有以下建议:

  如图,虽然学期中的时候增加了返回所有作业这一按钮,但整体而言使用起来还是不太方便。建议在评测、互测这一行最左端增加下拉式菜单等类似的切换课程的按钮,以便方便地切换历次的作业(顺便,作业的题目中可以适当增加关键字,如UML、电梯,目前仅仅是第x次作业,不太直观)。

  讨论区感觉使用这种筛选方法不太方便,可以借鉴传统网络论坛中分区设计,设置“官方回复区”、“提问区”、“讨论区”之类的可能会更加易于使用。

3.有关课堂的分享交流和课程提供给学生的自由度角度来讲,感觉可以考虑增加一次自由度较高的作业,实现方式比较多,在课上学生们讲自己独特的方法。在后几次作业时,虽然难度不高,不过代码量较大、课业较为繁忙,学生基本上都无暇去研究和细看其他学生的实现方法(刚开始几次可能为了找BUG会仔细阅读,之后基本上就很少有人下载别人的代码了)。这有些遗憾和可惜。

4.建议以后在某单元的前两次作业指导书中适当给出之后作业的要求,让学生有目的地进行可扩展地编写。而不是仅仅为了AC本次作业而下次完全推倒重构,或者为了可扩展性而写得过于冗长复杂。而学生在进行下一次作业时,将会直观地感受到自己上次作业的可扩展性如何,是否真的能扩展了,还是仍需重构,从而加深这方面的理解。

原文地址:https://www.cnblogs.com/kortez/p/11074909.html