2021-OO-UNIT4-总结

OO-UNIT4-BLOG

一、本单元作业架构设计

1.第一次作业

  • 第一次作业仅考虑类图,并未引入顺序图和状态图,因此架构设计相对简单。难点在于:对于UML图尚不熟悉,看了几遍课件后没找到有效的学习方法,同时对于StarUML等工具链操作不熟练。当然,在每个单元的初次作业,均会遇到类似问题。

  • 值得注意的是,本单元作业的接受传入数据部分和接受解析指令部分是分割开的:这意味着模型的建构与功能的实现在时间上严格分离。依据这两点,下文对于作业架构进行介绍。

  • 模型建构

    区别于JML单元对于性能的高度要求,本单元在运行时间上限制较宽。也就是说,可能出现超时的情况一般仅限于死循环等程序bug,在常规方法中不需要过多考虑。因此,采用多次循环的方式读取元素:读取每一种类别元素时,均对UmlElement数组进行一次循环。(当然,记得考虑读取元素之间的顺序关系)

    本次作业中,新建的类包括:MyClass,MyInterface,MyOperation。这是因为若构建层次化模型,这三种类图元素均需要添加下一层元素。同时,类与接口还有建立继承、关联、实现等关系的需要。当添加其他类图元素,无需新建类,只需依照层次关系添加到所属即可。上述的层次关系大抵如下:

    最上层MyClass, MyInterface
    中层 MyOperation, MyAttribute
    最下层 MyParameter
  • 功能实现

    在功能实现方面,大多数方法实现起来均比较容易,只要理解类图含义便不会有困难。值得一提的是getImplementInterfaceList方法:该方法需要返回指定类的所有实现接口。此处,需要考虑类之间的继承关系,以及接口之间的继承关系,如果采用递归的方式完成,经测试发现可能出现爆栈的问题。于是,通过采用先前未尝试过的数据结构:LinkedList,相当于一个队列,可以非递归地解决问题。令该队列存放接口。逐一取出队列中的元素,检查该元素是否存在于另一容器中。若不存在,则添加至该容器,再将该元素所继承的全部接口添加至队列。重复上述过程,直到队列为空。

2.第二次作业

  • 第二次作业添加了顺序图和状态图,实际上程序的增量并不算大(和电梯等单元的增量相比,任务量确实较轻)。并且,由于在上次作业中已经掌握了UML图的学习方法,因此此次作业理解起来也不甚困难。可以说,这次作业的架构设计变化不是很大。

  • 值得一提的是,在该次作业中部分功能实现借鉴了第一次作业中所提及的非递归方法,具体见上文。

3.第三次作业

  • 第三次作业增加了对于数据合理性的检查。具体架构延续先前的作业,关于各项检查均在对应类中添加对应方法以供调用,由于程序整体并不臃肿,因此没有再增加新类承担检查功能。值得一提的是,由于在前一次作业中忽略掉了元素:UmlCollaboration,因此导致本次的部分检查命令无法照常执行。因此,按照这样的架构实现UmlCollaboration:在新增UmlInteraction时,利用该元素的parentId构建MyCollaboration,添加至容器中。此后,在新增UmlAttribute时,判断属性的parent是否为MyCollaboration,建立对应关系。依照这样的逻辑,能够实现对应的判别。

二、四个单元的架构设计,OO方法理解演进

感谢课程组给我一个看从前代码的机会,不过已经看不懂了......

UNIT-1

  • 第一单元为表达式求导。在架构方面,采用了老师和助教所提及的工厂模式,构建一个工厂类,每个字符串传入工厂都能返回一种数据类型(表达式、乘积、和、常数等)。对于每类数据,都实现了其求导方法和化简方法,用不同于递归下降的方法完成了。(例如,对于某n项和,并不将其顺序向后处理,而是视作整体,将各项的求导和相加)

  • 第一单元的作业,应该是对于OO思想很好的启发。事实上,三次作业共写了三次代码,每次都以重构的方式开始,这也说明了程序扩展性的开始。从第一次作业厚重的面向过程痕迹,到二三次作业开始尝试工厂模式,都是OO方法理解提高的验证。

UNIT-2

  • 第二单元为电梯作业。在多线程的实现上,采用synchronized+代码块的锁设置,完成线程同步;在架构实现上,在电梯内置了一个Controller控制器类,统率电梯的决策,在二三次作业中还需要添加总调度器,进行统筹规划。

  • 第二单元作业,类之间的相互依赖关系更加清楚明了;重构次数减少,事实上,每次作业都在前一次基础上进行,没有重构现象;层次化设计良好。这些都证明了OO操作思想的逐渐提高。

UNIT-3

  • 第三单元为JML实践。本单元难度并不高,对于大部分方法,翻译JML规格便可以轻松实现。在架构的设计上,值得一提的是缓存思想的应用,并查集数据结构的使用,以及Dijkstra算法的高效实现。缓存的思想在此处不过多说明,并查集的数据结构主要在isCircle方法中使用。新增关系时,判断两人的祖先是否相同,若不同则需改变对应数据结构。经过资料的收集,Dijkstra算法可以应用堆优化相应数据结构实现

  • 第三单元的作业,没有让我特别get到OO思想考查的点。似乎很大程度上侧重于算法的设计?促使我重新学了一点数据结构和离散数学的内容。个人认为,在本单元中的提高主要呈现在对JML的理解上,促进了代码设计的规范化。同时,JML也给我们提供了一个良好的层次化框架,可以参考学习。

UNIT-4

  • 第四单元为UML类图解析。本单元难度仍然不算高。关于架构的相关介绍,在上文中已经有较大篇幅提及。

  • 有意思的是,不少同学都认为这一单元的完成和第一单元较为相似。但是,我在第一单元中经历了多次重构,痛苦不堪;在这一单元中却实现了较好的迭代开发,同时没有出现bug。个人认为,这在一定程度上体现了OO设计思想的提升。

三、四个单元的测试理解与实践推进

UNIT-1

  • 本单元利用正则表达式构造随机数据,并利用python的sympy库验证正确性,采用这样的暴力测试方法完成调试和互测。在这单元,所欠缺的是:手动构造数据的体验。

UNIT-2

  • 这一单元的测试,一部分延续了上单元的暴力构造数据方式,并在python手写对拍判断逻辑。这样的测试方式的弊端是:由于随机构造的数据强度较弱,因此当程序存在较低级错误时,两三条数据便出锅;当程序的错误比较隐蔽时,跑上成百上千条也难觅bug。

  • 于是,走向了手动构造测试数据的道路。通过定时投放,多次尝试同一条数据(由于多线程程序的难复现性,必须如此)。通过这样的方式,找到了自己的若干bug,并在互测中取得一定成效。在这点上,应该是测试方法的进步和补全。

UNIT-3

  • 这一单元的测试仍然延续了上述方法:暴力构造数据+针对程序手动生成样例。由于课程组介绍了:Junit方法,因此也结合这一新的工具对程序进行单元测试检验。

UNIT-4

  • 容易发现的是,这单元的测试数据并不方便暴力生成(且没有意义)。因此,根据自身对于UML图的理解,构造了测试数据,成功查到bug。

  • 值得一提的是,在构造UML类图数据时,可以在Java中编写程序,再将其导入StarUML中生成对应数据

四、课程收获

1.OO思想的提升

  • 经过一个学期的课程锻炼,我的面向对象思想有了较大提高,这一点在历次程序所花费时间和取得成绩上也有所体现。此处,我认为OO课程组传授给我的面向对象思想并不仅仅局限于封装、继承、多态等OO常见元素的编程实现,而是带着“万物皆对象”的思想审视程序任务,将各个层次组成抽象化看待,设计构造后在代码中实现

  • OO思想的提升也进一步促进了层次化设计的能力有所进步。经过多单元的作业,我从开始时的屡次重构,再到之后的拓展迭代,在架构的设计方面有了较大的提升。在后几次作业中,我也改变了莽撞编程的方式,而是首先考虑架构的可拓展性,完成层次设计后再进行编程。

2.Java编程的掌握

  • 经过了12次作业的艰难完成,可以说得上较为熟练地掌握了Java编程。

  • 对于Java编程的学习体现在多方面。在Pre作业中,掌握了Java程序的基本写法,继承、实现等功能的Java实现,抛出异常的规则等。在第一单元作业中,接触了Java编程常采用的设计哲学(如工厂模式等)。到了第二单元作业,仿佛拓展了另一片天地般地学习了多线程在Java中的实现。而第三单元与第四单元则提供了JML规格以及UML类图等供人实现,这在一定程度上提供了编程学习的样本示例。

3.学科交叉学习

  • OO通过研讨课、实验课、互测等多环节的任务,有效地提高了多方面能力。实际上,它也提供了与其他学科相互结合的学习机会,以下是两个例子。

  • 在第二单元作业(电梯)到来前的研讨课上,我分享了多线程编程相关内容。为了完成对应讲解,我上网搜集资料,准备ppt等,从基础概念上加强了对于进程和线程、线程同步等内容的理解。而恰好,本学期的OS操作系统课程也涉及了相关内容,这对于OS的进程和线程部分学习打下了基础。

  • 在第三、四作业中,有部分对于图论等内容的考差,同时对于数据结构也有较高要求。为了实现并查集、Dijkstra算法、堆优化等内容,我复习了此前的数据结构及离散数学等课程内容,并在网上搜查资料、与同学讨论数据结构的选取。这在一定程度是其他课程的实践,起到温故而知新的作用。

五、三个建议

1.实验课设置

  • 实际上,并不太清楚实验课的具体作用(个人理解的一个用处是实验课提供的代码框架可以对对应单元作业起到示范效果)。在答案并未公开的情况下,并不确定自己的结果是否正确,与同学的讨论也无法得到印证。因此,是否可以考虑放出课上实验答案?

2.课程安排

  • 大多数身边同学一致认为:后两次作业相比于前两次作业难度降低较多。不仅完成时间大幅减少,最后的成绩也比较令人满意。虽然这其中离不开自身面向对象编程能力的提升,但是单元的难度差异还是客观存在的。

  • 从后期的学业压力来说,这样的安排有合理之处。但是对于OO课程本身而言,似乎先易后难、逐渐深入会更有益处。或者,可以适当调整每单元作业完成时间,侧重于难度较高的单元。

3.琐碎建议

  • 每单元的训练内容存在感不高,在没有加以强调的情况下,每单元的训练都在繁忙的学业内容中被忽略掉了,没有起到实际作用。

  • JML和UML部分的规格规范存在表达不明确的问题,每次都要经过讨论区的大量翻阅、和同学的大量讨论才能清楚,花费的时间没有意义。可以向下届学生明确存在争议的地方。

  • 课程的迭代扩展仍然有值得改善的地方。例如,电梯作业中第二次作业至第三次作业的扩展内容较少,由于并不强制换乘,部分同学并未采取换乘架构仍然取得较好成绩,没有起到相应学习作用。类似的地方还有比较多,可以再加以打磨。

posted @ 2021-06-26 11:14  lazyc  阅读(119)  评论(1)    收藏  举报