BUAA_OO_UNIT4

BUAA_OO_UNIT4

1. 架构设计

1.1 第一次作业

​ 由于官方自带UML解析器了,我们只需要分三次扫描把elements里面的东西全读出来就行。第一次把class、interface与associationEnd读出来以便后续关联;第二次读出余下的除了parameter之外的元素;第三次读出parameter即可。为了便于在遍历时进行关联,在UmlInteraction中需要增加许多HashMap存储id与实例的对应关系。

​ 根据需要,把class、interface、operation这三个官方类进行封装,架构如图所示。

​ 由于查询时图已经构建完成,故每次查询都可以进行缓存,待再次查询到时返回结果即可;同时,每次查询都会向下调用子类方法,保证在子类抛出对应的异常类型,便于管理;而对于某些查询可能会抛类型异常,只需要提前做标记,在查询时检测标记抛出。

​ 对于继承的类、实现的接口等方法,我采用DFS进行解析。首先让可能存在的父类进行更新,然后沿着链依次返回更新完毕的HashMap来更新子类。这样查询一次子类就可以更新其所有父类相应的领域,保证查询父类时能够立刻返回。

1.2 第二次作业

​ 依旧采用三次扫描,第一次多读入stateMachin、interaction与region,第二次读入state、lifeline与transition,第三次读入event、message。

​ 对于新增的类,同样进行缓存查询、DFS来保证功能正确性,与上次作业一致。

1.3 第三次作业

​ 本次作业主要进行有效性检查。架构图跟第二次作业完全一致,就不放了。

​ 方法跟查询类似。在类中增加标记,查询下降到子类更新标记,再遍历子类看有无标记,即可实现有效性检查。基本方法如下。

规则 方法
R001 用HashSet进行检查
R002 将入度为0的节点剔除,删去与后续节点的边,重复该操作
R003 更新时HashMap的id不重复
R004 更新时HashMap的id不重复
R005 在顶层检查
R006 在顶层检查
R007 检查HashSet是否有对应元素
R008 对initial state特判

2. 架构设计与OO方法理解的演进

2.1 第一单元

​ 第一单元主要是对JAVA语法的熟悉以及OOP的初步认知。虽然经历过重构,但彼时架构思想比较幼稚,不能很好地将进行抽象与层次化设计,故构建出来的架构比较混乱,存在冗余。

​ 本单元主要把多项式、三角函数、因子等都抽象为项,通过调用项的求导方法来向下调用具体类型的求导方法,而具体类型继续继续深层次调用,实现各司其职,将求导得到的String加入到StringBuilder中;而递归下降的解析也同理。

2.2 第二单元

​ 第二单元提前了解了三次作业可能的迭代开发方向,为后续开发留下了空间。

​ 主要的架构思想为生产者-消费者模型,通过Input不断往货架上放入乘客,而电梯借助调度器间接访问货架,从中获取下一步的目标再从货架上取出乘客;而电梯本身存在状态转移,在特定状态下只会执行特定操作,此时电梯只在特定状态下间接关注货架变化,减少发生线程不安全的可能。

​ 本单元将不同功能模块尽可能地划分开,尽量符合高内聚低耦合的设计思想,让各部分各司其职、分工合作,实现电梯的高效调度。

2.3 第三单元

​ 第三单元说实话基本不需要自己进行架构设计,无非是权衡数据组织形式用HashMap、ArrayList等进行数据存储与缓存,实现高效应答。

​ 本单元感觉主要是在拼图。课程组已经给了你大致的框架了,你只需要把算法一个个填上去,合理地维护中间变量以保证不出错即可,并无太大的个人发挥空间。对于OOP的理解进展一般,倒是对于规格化设计、契约有了进一步的理解。

2.4 第四单元

​ 第四单元架构在上面,在此不赘述。

​ 本单元主要介绍UML模型。感觉UML模型是一种介于需求与代码之前的东西,有些类似于JML等规格,因能够形成具体图像而显得更加友好。它向上承接需求,能够帮助客户更好地知晓程序的设计、知否满足需求;向下能够指导我们码代码,是一种比自然语言严谨、比规格与代码好理解的工具。通过将数据、类等抽象为模型,我们能够更好地组织起不同模块间的关联,从而满足OOP。

3. 测试理解与实践的演进

​ 第一二单元主要靠自动测评机与手动构造样例。测评机在参考往届测评机后,依样画葫芦地搭出自己的测评机;而测评机的数据主要在理解指导书要求后,针对性地构造出有不同偏向的数据。第一单元通过跟标程的对拍,随机取点比较来进行;第二单元主要做了一些检查,如人数、时间、楼层等等,保证了电梯功能的正确性。互测其实跟自己测试差不多。自动测评机黑盒测试,然后通过奇奇怪怪的手动样例进行轰炸来找bug,效果还行。

​ 第三单元使用JUnit进行单元测试。通过人工覆盖所有的逻辑分支与可能的情况,尽量保证在不同应用场景下能够正常运作。

​ 第四单元通过手动构造样例进行测试。由于UML的特殊性,不太好搭测评机,JUnit写起来也挺怪的,于是通过构造有一点强度的图来进行测试;同时,通过自己与别人的样例,与同学的程序进行对拍来找错。

​ 感觉上,测试其实就是一种对程序所形成空间的一种验证。黑盒测试有点像遍历这个状态空间,很多时候它相当有用,能够通过一些corner case来hack出状态空间里有bug的地方,但也有很多情况下我们根本无法遍历状态空间;而白盒测试有点像对状态空间形成的定理、推论等等的一个推导与证明,它能够覆盖抽象的情况,弥补黑盒的不足,但这种抽象本身具备相当大的难度。二者结合的话,能够较好地验证程序的正确性。

4. 课程收获

  • 注释与文档:这是我在OO课上逐渐养成的习惯,感觉在后期为我带来了相当大的便利。刚开始写OO真的是狂妄无知年轻气盛,不写注释与文档就开始硬莽求导,第一次作业磕磕绊绊,然后因为看不懂自己在做什么,于是重构了,于是开始写注释;再之后因为内容较多,一时半会搞不定,容易忘了之前怎么想的,于是拿到指导书前会写文档,大致设计一下,有新思路也会及时写进去,这样在当下开发、迭代开发都带给我很大的便利。
  • 架构设计:后期写OO的时候,更多时间是花费在写文档、架构设计上,写代码就照着文档翻译一遍 (虽然有时候还会de文档的bug),让我对合理的架构、层次化设计等有了进一步的理解。感受最深的莫过于第二单元,所谓一个优秀的架构应当是能够兼顾功能与性能的。
  • 测试:终于主动 (被迫)学会了一些测试的方法。之前的数据结构跟CO都是靠着测评机跟大佬的数据苟过来的,啥也不会。现在能够照猫画虎地搭建简单的测评机,也能够生成有一定强度的数据;同时也学会了单元测试这样形式化验证的方法,感觉颇有收获吧。
  • 代码风格:大概也能算收获?之前CO写的代码虽然不至于不堪入目,但总觉得不太想再看一次;现在经过一学期checkstyle的训练,基本上可以不检查也能代码风格优良,再次阅读、修改的时候也感觉看起来颇为顺眼,变量命名也终于带脑子了,没有了xyz、abc这样不明所以的东西。
  • 语言:应该能算吧?之前比较多的接触C,这学期接触JAVA跟python之后真的感动得要落泪,看着OS的C语言感觉一眼都看不下去了。一学期的学习让我掌握了JAVA的一小部分应用以及python相当浅显的使用,感觉也是收获吧。

5. 三个建议

  • 个人感觉JML放在第三单元有点怪,可能放在第一单元比较合适。感觉第一单元最主要还是在学JAVA语法与最基本的面向对象思想,此时通过JML的官方代码与规格,能够很好地帮助像我这样没有JAVA基础的人了解JAVA,同时明白架构、涉及、迭代开发、测试的重要性,避免后续频繁重构
  • 实验课基本不给解析与反馈。我不太明白这种做法的原因,但我只知道每次我花了两节课的时候做实验,却没有任何反馈与解析,也不知道完成的怎么样,结果就这样不了了之。感觉下一届可以给出一些反馈解析,这样可以对照着学一些东西。
  • 多线程互测的体验有点怪。总所周知,多线程比较看脸,要是运气好了别人死活刀不到你。由于互测时似乎只跑了一次,故有时候在自己机子上跑一遍就出bug的测试用例,扔上去如同石沉大海,而且每次cd相当长,导致不太容易有很好的hack体验。由于线程调度具有不确定性,我感觉可以在互测上跑个十遍八遍,然后再来判定,抓到部分漏网之鱼
  • (从0开始数,所以这里是第三个建议) 感觉UML可以跟JML一样发一个手册,对类图、顺序图、状态图进行一个更为详细地介绍。类似于JML,课上受限于时间,不太能够详尽地讲一些东西,这时候通过课下的手册以及样例,能够比较快地上手,不至于在实验课手忙脚乱。

6. 感受

​ 课程收获已经写了,这里就自由自在地写点东西吧!

​ 首先感谢研讨课、讨论区的各路大佬的帮助,没有你们我现在有可能就在补给站畅游了;再感谢老师的辛勤付出,为大家传道授业解惑;最后感谢威武的助教大大们,没有你们的帮助与解答我大抵是顶不住OO的。

​ 我终于免费了!互测提心吊胆的日子、de不出bug惊心动魄的日子终于(暂时)过去了!又能活蹦乱跳了(暂时)!

posted @ 2021-06-22 16:11  _Winterfell  阅读(67)  评论(0)    收藏  举报