OO第四单元(UML)及课程总结

OO第四单元(UML)及课程总结

      OO课程完结撒花!最后对第四单元以及课程进行一个整体的回顾。

本单元架构设计

      本单元最终要求完成一个UML解析器,实现类图、顺序图、状态图相关信息查询功能,并进行有效性检查。

      三次作业架构上是增量开发,并没有太大的重构,因此仅放出最后一次作业的架构:

      MyUmlGnerationInteraction是负责完成读入模型时的建模,并提供各种查询的对外接口,其中含有的Validator是对所有的有效性检查进行封装。对于输入的UML实例模型的建模,实际上大部分是依据各元模型的关系直接建模,只有上图中My系列对应元模型进行了封装。整体而言,整个UML模型被分为类图、顺序图、状态图部分:

  • 类图

      由MyClassMyInterface组成,这两个类在建模时就已经存储了对应的树结构所有信息(即所含有的attribute、operation、各种关系等)。至于继承关系则是采用建立图模型的方法,每个结点存储其父亲,方便逐级查找。(因为查询都是针对每个MyClass对象,所以这里没有再封装成一个类图类)

  • 顺序图MySequenceDiagram

      存储所有MyLifeline。其中MyLifeline中直接存储发送与接受的Message数量(查询指令只关注数量)。

  • 状态图MyStateMachine

      存储所有状态MyState和迁移MyTransition。MyState也是采用建立图模型的方法,方便快速找到下一个可以到达的状态。MyTransition则存储了对应的UmlEvent。

      对于各个方法,读入模型时的建模比较复杂,采取的方法是读一遍时进行元素分类,再逐步按照树形结构存储信息;指令查询时,由于有较好的封装以及建立的图模型,方法都不算太复杂;检查有效性时,为提高性能,在检测继承环时使用了tarjan算法。


架构设计及OO方法理解的演进

架构设计的抽象性与层次性

      其实从第一单元开始,就意识到了架构的重要性。而好的架构的一个特点就是有较好的扩展性,在课程中具体表现为一个单元的迭代开发。而要做到这一点,个人认为做好抽象这一步的工作,理清各对象的层次。

      在第一单元表达式求导当中,如何解决不同因子的求导,换而言之拥有一个统一的建模,其实就是一个值得思考的架构问题。最开始的时候我尝试抽象一些共同特点的对象,最终根据求导的步骤,得到了“表达式—项—因子”这样的基本模型。这样子的架构其实已经基本支持了第三次作业的内嵌因子等扩展,在实际的迭代当中重构的工作量也不算太大。事实上现在回顾这个模型,其实正是抽象出了加法类、乘法类与因子这三种不同求导特点的类,其中因子类其实是一个抽象类,通过子类具体实现某种因子的求导。

      在第二单元电梯作业当中,实验课上的代码其实给了很好的架构思路。个人看来实验课代码的框架其实是十分有层次的:全局调度器(线程)的设计就为输入线程和若干电梯线程之间提供了一个较好的桥梁。我在具体实现过程中,是线程之间两两共享一个共享对象(按照顺序),因而减少了因为多个线程共享同一对象带来的死锁隐患。而且这也暗示了乘客分配策略与电梯运行策略其实可以分离,也有助于整个架构的设计。

      第三、四单元因为有官方代码(而且侧重点不同),所以基本上不太涉及架构。

      总而言之,架构设计其实对抽象思维与层次设计有极大的要求,也锻炼了我在这方面的能力。至于继承、多态等,更多的是实现对象之间的层次的方法。

面向对象的新视角

      相比于以往的面向过程式编程,面向对象可以说是一个新的解决问题的视角。面向对象式编程,更注重有什么对象(行为主体)以及之间的交互。其实我感受最深的一点是封装与对象的自我管理,每一个对象可以管理自己的状态,提供交互接口——这种封装可以减小对象间交互的复杂性,在面对复杂交互问题当中或许是一个可以尝试的思路。


测试理解与实践的演进

      课程中的测试主要包括正确性测试与性能测试两个方面。在具体的测试当中,均采用了手动构造与随机生成两种方法。在正确性测试当中,手动构造主要涉及边界条件的测试,而随机生成除了大规模轰炸以覆盖多数情况之外,还有机会触发一些程序实现上的隐患(比如空指针)。而性能测试方面,随机生成比较容易实现大数据量,但是有时候还需要针对代码特点(算法、数据结构),对一些比较复杂的方法构造特殊数据进行测试。

      当然其实在课程当中也学习了面向规格、模型的测试,理论上可以更高效地覆盖所有情况。但是似乎还是实践较少,就不过多提及了。


课程收获

1、养成动手前设计架构的好习惯。

      根据多次实践经验来看,虽然设计架构会花费不少时间,但是想明白了再写,总比一边想一边删删改改所花费的时间少。当然这不是说一定要把每个细节都想明白了再去动手,但是大体的框架(有几个类、基本的交互)还是想清楚再写。这样不至于写到某个方法的时候突然出现无法完成、或者交互复杂时思路不清晰(比如针对某一个行为,每个对象分别完成什么)。

2、相对完整的开发流程。
      主要指迭代和测试。课程的迭代开发使我们更多的思考可扩展性,而强测等测试机制则让我们(打破惰性)主动进行全方面的测试。这比简单地完成一段程序有更多的工作,其实锻炼了我们更多的能力。

3、抗压能力与时间管理能力(治好了拖延症)。


课程改进建议

1、增加第三单元JML书写(自行设计)训练。比如可以挑选一些需要考虑多种情况(多behavior),或者涉及封装数据的一致性(对要变的数据考虑齐全)的方法,通过自然语言描述方法的作用,然后让同学们自行设计JML并且实现。虽然批改JML会增大工作量,但实际上

2、及时反馈实验结果。实验中有些问题可能大家都有疑问,所以可以考虑及时反馈,同时也能加深大家对实验内容的思考——毕竟实验的设计初衷也是为了引导大家学习知识。

3、讨论区设置问题下方直接回复的机制(爬楼太难了),这样方便大家把相同或类似的问题集中讨论。

posted @ 2021-06-26 20:42  daydayup_2021  阅读(86)  评论(0)    收藏  举报