Unit4-窝窝之昆崚
全文共3012
字,推荐阅读时间10~15
分钟。
文章共分五个部分:
作业分析
Unit4要求我们实现UML解析器,迭代过程主要是增加对不同类型UML图的解析功能。本单元的作业分析有独特的地方——因为三次作业都采用了一致的架构,因此以第三次作业的UML
图为例即可了解整个单元迭代开发的过程。
![](https://i.loli.net/2020/06/13/3uNSWz8bhMTsqdR.png)
从UML图可以很直接地看出来整个系统的模拟思路:通过分包策略,让各种UML图的解析和交互类分离,可以达到在增加新的UML图时,只增加一个包和在交互接口中增加相应方法即可。
第一次作业
第一次作业要求我们实现UML类图解析器
UML图如下
![](https://i.loli.net/2020/06/13/BrAt4zxSEWUHLaM.png)
- 代码结构
结构大致可以分为两层:交互->解析。在交互层不需要考虑解析出的元素是如何存放的,只需要处理好从解析层抛出的异常即可。
- 复杂度分析
![](https://i.loli.net/2020/06/13/4MfjVxdLKubrGS2.png)
从反馈结果可以看出,因为增加了缓存机制,在getSpOpCnt
这个方法中调用了很多子函数,造成了三个复杂度都很高的情况,进而还影响到了类图的交互器。目前还没有找到比过滤方法更好的办法实现对特定要求方法的数量查找,如果有同学有更好的思路,欢迎交流。
第二次作业
第二次作业要求我们增加对顺序图和状态图的解析功能
UML图如下
![](https://i.loli.net/2020/06/13/yxaD8FIHYS1lwC2.png)
- 代码结构
代码架构基本延续了第一次的设计风格,只是增加了一个总交互类和两个子交互类以及相应的解析类。
- 复杂度分析
![](https://i.loli.net/2020/06/13/7wkarOAWgPpQcHB.png)
![](https://i.loli.net/2020/06/13/qHKM53n6EoIUNCx.png)
从反馈结果可以看出,复杂度和第一次区别不大,原因主要在于类图的解析元素相比于顺序图和状态图都更多,所以复杂度也会更高。
第三次作业
第三次作业要求我们进一步实现UML规格检查。
UML图如下
![](https://i.loli.net/2020/06/13/F3YSsJ6MNq8Bbjw.png)
- 代码结构
代码架构和第二次相同,采用了检测和构造并行的思路,因此并没有单独构造一个检查类。
- 复杂度分析
![](https://i.loli.net/2020/06/13/C987cOi3nbYGQmU.png)
![](https://i.loli.net/2020/06/13/3RzfJAhSXKVxO6L.png)
从反馈结果可以看到,复杂度依然来自于类图解析器。如果可以的话,请对于类图解析有独到的见解的同学不吝赐教。
烘烤OO的精华
小节标题来自于O'REILLY出版社的“口头禅”,选择它作为标题的原因很简单:和咱们这门课的主题相呼应。课程组的老师们在一学期的课程中反复向我们强调:OO不是Java程序设计,而是面向对象的程序设计方法课程。
现在回望起来,发现自己对这句话的理解也是随着课程的进展逐渐变化的:
-
第一单元我愿意把它叫做
C-Java
时期,因为这个时候自己的脑海里面向过程编程的思想还很牢固——什么事只要一个主函数就搞定了。这也直接造成了遇到稍显复杂的工程就难以下手的情况,比如第三次作业,最后自己硬套上了面向过程的表达式树,虽然可以实现功能,但是一旦想要改动一点点东西,比如增加一种求导函数,确实就会捉襟见肘。后来单元研讨的时候才发现如果采用OO的想法,把”分而治之“贯彻到极致,是可以实现一个非常灵活的架构的。这个时候我发现了一个影响我后来开发过程的小技巧:分包。
(如果想可以看看之前的博客,会发现后来几乎每次作业我都会分包) -
第二单元我们接触了现代开发的基本功:多线程。
这一单与我的评测机制产生了巨大变化,具体会在下一小节提到,这里就不再展开了。
-
第三单元我想要把它看成”团队开发“的先导训练。为什么这么说呢?世界代码千千万,一人不可能写得完,就比如Windows的那几千万行代码,一定是团队开发的。团队里也要有分工:有人擅长架构,有人擅长编码,那么JML就是这两者之间最好的桥梁之一。因此第三单元的体验非常开心,原因就在于课程组为我们当了一个技艺高超的架构师,让我们只要照方抓药就好。
值得一提的就是最后的复杂度分析:不比不知道,一比吓一跳。第三单元的架构复杂度是最低的,这也让我对规格化编程愈发重视。
-
第四单元我们走进了UML的世界。之前听学长提起UML的时候说:
UML需要有代码经验的产品经理画才有威力,要不然就是在圈地自萌。
当时并不明白这是为什么,现在我大概有了一点感觉:UML绝不等于画图,这种模型化的语言和JML一样,是蕴含着丰富的逻辑的——一个类下面的”树“可能枝繁叶茂也可能冷冷清清。如果只是画一些方块和线条连接起来,那只能叫做建模草稿,绝不是成熟的模型描述。
综合看来,OO课程用了五个月,让我们体验了从Code Man到PM的整个历程,这个时间控制得是非常精准的,每个部分都让大家收获满满,却也意犹未尽。
现在如果让我解决一个生活问题,我很可能会先拿出纸笔,画出整个系统的架构,就像当初设计CPU一样,把高内聚低耦合的思想融合进去,最后才会是写代码的工作。后面几次作业我都采用了这样的方法,发现其实如果架构建立起来了,写代码只是一个收尾工作而已,并不是占用时间最多的环节。
评测相关
评测机架构
首先是一组数据:
- 这一学期共12次作业,我一共用了12次评测机。
- 这一学期共4个单元,我一共搭了4次评测机。
也许你会很奇怪为什么第四个数不是12,原因就在开发第二单元的评测机的时候,我一鼓作气把Java里OO想法用到了Python里,虽然有些地方受限于语法等因素不能完全一致。但是后来每次作业,我都不需要再搭一次评测机,相反,只需要增加一些评测逻辑即可。(这有点像把评测机当作了一个大对象)
具体的文件树如下
── center
│ ├── auto_test.py
│ └── tempCodeRunnerFile.py
├── data
├── download_data
├── factory
│ ├── arrangement_data.py
│ ├── class_extractor.py
│ ├── class-info-extractor.jar
│ ├── collaboration_data.py
│ ├── collaboration-info-extractor.jar
│ ├── gene_data.py
│ ├── name_data.py
│ ├── single_data.py
│ ├── state_data.py
│ ├── state-info-extractor.jar
│ ├── traverse_data.py
│ └── uml-homework.jar
├── lib
│ ├── jar-one
│ │ └── xxx.jar
│ ├── jar-two
│ │ └── xxx.jar
│ └── jar-three
│ └── xxx.jar
├── output
│ ├── new-asso
│ ├── new-asso-and-imp
│ └── other-com
├── result
│ ├── new-asso
│ │ └── result.txt
│ ├── new-asso-and-imp
│ │ └── result.txt
│ └── other-com
│ └── result.txt
├── ruler
│ ├── spj.py
│ ├── std
│ │ └── xxx.jar
│ └── tempCodeRunnerFile.py
├── server
│ ├── get_graph.py
│ ├── get_output.py
│ ├── get_result.py
│ ├── get_sub_result.py
│ └── time_holder.py
├── summary
│ ├── digit
│ │ └── spj_result.txt
│ └── graph
│ ├── line.png
│ ├── mvp_bar.png
│ └── stats_bar.png
└── template
center
:存放评测的核心控制代码,用于组织编译->运行->反馈
功能data
:存放自动生成的数据download_data
:存放测试中出现问题的数据,可以用于回归测试。factory
:存放数据生成代码lib
:存放JAR
包output
:存放各个测试代码的输出result
:存放各个测试代码的结果ruler
:存放标程或评测逻辑(即spj
的逻辑判断代码)server
:用于适配服务器端的调用代码summary
:用于存放反馈整合后的结果
评测机演示
- 使用前将待测试JAR包放在lib文件夹下
- 运行center文件夹中的
auto_test.py
文件 - 从summary文件夹中得到反馈结果(文字+可视化)
关于可视化,在第二单元体现的尤其明显,可以看这篇博客,有非常详细的展示和注释。
评测机开发
目前可扩展架构的评测机均已经在Github上开源
- 第二单元电梯调度:https://github.com/SilenceX12138/auto-test-machine-for-elevator
- 第三单元规格化编程:https://github.com/SilenceX12138/BUAA-OO-auto-test-machine-for-network
- 第四单元UML解析:https://github.com/SilenceX12138/BUAA-OO-auto-test-machine-for-uml
如果有任何疑问,请联系silencejiang12138@gmail.com,或者直接在Github上@SilenceX12138.
课程体验感受
一学期的OO课程让我体验颇深,从第一单元的最后总结时的不甘(想知道为啥的话可以去看看第一单元的博客),到现在依然愿意和大家一起讨论、互帮互助。OO教会我的不仅是面向对象的思维方式,更是待人接物的道理和心态。
如果能对二月的自己说一句话,我会告诉他:好好享受接下来的五个月,你会发现自己会有更多的可能性。
如果能对未来的自己说一句话,我会提醒他:别忘记了OO那年的春夏,你会永远为了当初无畏的少年自豪。
一些小小的建议
- OO课程绝对能够称得上学院里体系非常成熟和完善的一门课,对于课程设置并没有什么建议或者意见。这里想引用一句话:大学生还不够格说那些课有用还是无用的,最需要的是认真对待每一门课。
- 第三单元的指导书修改的次数
稍微有些多了,虽然不影响主干逻辑,但是一些细节对于同学们也是非常重要的。这个问题不能光归咎于课程组,JML工具链的不完善也是一个不能忽视的问题,所以希望来年通过一些办法(比如开发课程专用的JML检查工具),为学弟学妹提供更好的体验。 - 实验课的时间可以适当提前,留给同学们更加充足的准备时间。现在都是前一天晚上或者当天早上进行内容发布,难免出现时间紧张的情况。
最后,再次向OO课程组的所有老师、助教以及讨论区中的同学们表示最诚挚的感谢!
Good Luck And Have Fun!