面向对象第四单元总结

面向对象第四单元总结


一、架构设计

第一次作业:

类图看起来很复杂,但实际上结构很简单

第二次作业:

在原来的基础上新增mylifeline、mystatemachine、myregion、mytransition(这个地方我的状态图和顺序图的设计显然不够合理,后面会分析到)

第三次作业:

新增了collaboration,但是总体架构和第二次几乎一样,主要是全局进行有效性检查,算法层面的考虑更多。因此就不放第三次作业的架构了。

总体架构设计
  1. 基本架构设计:这次的UML架构设计我是基本跟着指导书做的,因为UML本身就具有很明显的分层管理关系,比如myclass和myinterface会具有operation和attribute两个属性,mystateMachine会管理region等等。
  2. 细节处理:为了简化查询工作,我在Interface内也加入了parentInterfaceMap(interface继承的接口),在myclass加入了父类的Id,这样就可以直接通过自己访问父类或者继承的接口,有利于搜索。
  3. 在全局分别建立所有结构的idxxxMap和namexxxMap(idxxxMap是指Key值存的是id,namexxxMap是key值存的是name,但由于存在重名的情况,所以value使用的hashset),这样在全局也可以直接访问这些数据,不必多层搜索。

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

OO课让我第一次学习到了面向对象的特性,同时掌握了JAVA的使用,受益匪浅。

第一单元:表达式求导

架构设计:

(这是第三次作业的贴图,第一次作业压根就没有将expr、cos、sin等分开的想法,实在太丑陋了)

在这次作业里面,我学习到了正则表达式的使用以及递归下降,从这时领悟到了Java内的递归的写法。同时我明白了如何区分和细化不同对象,区分不同方法应该执行的功能。因为最开始我将格式判断杂糅在求导过程中,导致结构十分不清晰,后来我将格式判断单独封装成类,求导过程和判断过程分隔开,结构就清爽了很多。

最让我印象深刻的就是坏的架构对迭代设计的毁灭性影响,不清晰的架构会导致每次作业都重构(第一单元三次作业我重构了两次),之后的三个单元就都没有重构了。架构设计要尽可能符合题目要求和设计,不要自己自创很多奇怪的类,比如在第四单元的UML设计,就有很明显的层次关系,直接根据它的结构设计即可,不要自己瞎写。

第二单元:多线程电梯

架构设计:

img

简化版关系图:

img

电梯作业的架构设计就更加简单了,根据功能不同划分为输入线程、电梯运转线程、调度器,再利用上现学的生产者-消费者模式,一个电梯系统就这样组装好了。

在这次作业里面,我对面向对象这一特性的理解更上一层楼。如果说第一单元只是交给了我应该根据数据特性不同区分对象,那么第二单元就告诉我应该根据对象功能不同区分。每个对象各司其责,不必care别的对象的功能和职责,利用共享数据的变化进行通信和协作。同时还看到了在Java里面应该如何实现对象间、线程间的交互(尤其是线程间这种通信方式),给我的OS也带来了不少帮助。

第三单元:JML规格

架构设计:

img

第三次作业可以说是几乎毫无架构,因为绝大部分的架构都是由助教给出来的,我们的任务更倾向于填空。但是我在这次作业里明白了规格的阅读和书写,以及中间变量的维护的重要性。

如果说前两单元的设计是让我们自由发挥奇思妙想,那么这个单元就是限制我们的想法,只能在数据结构和算法上小有变动。并查集、dijstra+堆优化都让我大开眼界(之前从来都没写过哈哈哈哈),用上了Hashmap并对此深深着迷。

第四单元:UML设计

第四单元的架构图已经贴在了第一部分,主要写写我对UML的理解。最开始的时候,我以为会让我们写一个UML画图器(因为群里的助教都把这单元概括为画图了),就是把信息给我们,我们自己来画图,最后验收图片,因此还为此紧张很久。

在这次作业里面我对OO架构的理解就是,根据逻辑分层关系进行对象的设计,同时在全局建立对所有数据的索引,这样既能一层一层地进行某些操作(比如判断格式、统计操作),也能直接访问某些数据。

三、测试理解和实践

由于水平和时间有限,这四个单元的作业我都采用的手动构造数据进行验证,而没有使用评测机。我对测试的理解就是分为两类:有目的性地构造数据,通过简单排查来寻找可能出现的Bug以及大量数据疯狂黑箱轰炸。

  • 有目的性地构造数据是指从数据类型(比如程序能否会使大数溢出)、逻辑设计(比如UML里面设计很多环型设计,重复继承、重复实现等)、极端例子(比如第一单元表达式求导里面构造(((-((x)))))以及空表达式)。这种测试方法简单并且hack别人成功率也比较高,但是弱点就是无法全面分析考察,因为自己构造数据始终不够客观,会出现很多逻辑漏洞。

  • 大量数据轰炸虽然没有目的性,但是在一定程度上做到了面面俱到(同时也考验设计者对数据的了解程度,有时候指导书模糊不清的地方很容易给人带来误解,从而对数据设计有偏差之处)。希望以后的我还能有机会学习评测机的书写qaq

  • junit测试我个人是不太推荐的,因为并没有从中体会到优势所在,所以就略过不写啦。

  • 形式化验证还没学会,虽然大佬们已经分享了若干次,但是一直没有机会自己上手操作。假期会多看看形式化验证的资料学习的。

四、课程收获
  1. 知识层面上:学会了递归下降、正则表达式、多线程、调度规则(本质是磁盘的调度)、线程交互模式(生产者-消费者、黑板模式等等)、dijstra算法+堆优化(寻找单源最短路径)、并查集(判断是否连通)等等。
  2. 面向对象层面上:学会了Java,明白了如何区分对象并且封装成类(根据数据的特征、对象的功能和逻辑关系),学会了对象间的交互(利用共享数据),线程间的交互模式。
  3. 心态层面:最开始学的反而是最难的部分,导致我高强度重构,并且对OO产生了恐惧,一想到OO还没着落晚上就焦虑得睡不着觉,但是如果熬夜写代码,最后的成果也是思路混乱的。后来我渐渐掌握了自己写OO的节奏,周三看题,周四构思,周五白天写代码(严格控制在十二点之前写代码,一过十二点就开始睡觉),周六debug和评测,周日摸鱼写OS。写代码并不是一个心急的事情,至少对于我来说不是,将自己最清醒的时间段留给OO,也不必过度焦虑,相信自己没有想象的那么菜就可以了。
  4. 交流层面上:OO不是一座孤岛,尤其是对于菜鸡来说。探讨算法和Bug原因以及小嫖一下别人的测试数据是通关的必经之路。出现bug就可以在评论区里寻找一下(一般都能找到回答),多阅读往届学长学姐的架构设计和算法总结,会少走很多弯路。不要害羞觉得不好意思,毕竟交流让人成长嘛,闭门造车只会加重自己的负担。
五、课程改进建议

OO是我大二下最满意的课程了,所以只能从某些细节提一些建议(可能有点吹毛求疵)

  1. JML:JML并没有太多的体现面向对象的特点,并且我认为在现实生活中提前确定好如此详细的规格是否不太可能,而且规格太多有时候就会忘掉自己曾经写过什么。所以我认为JML是否可以替换成别的单元。
  2. UML:UML指导书的描述有点含糊不清,比如有的attribute并没有所属的上级,这就导致我在添加属性给类或者操作的时候会抛空指针,评测出错的时候就一脸懵逼。希望指导书可以再详细一点,把没有规定好的地方标注出来。
  3. 互测:既然OO重心是在面向对象的把握,为什么把hack别人作为一种评估方式呢?很多人会花大量时间在写评测机和hack别人上,对自己的架构和算法却没有太多的考量,私以为违背了OO这门课的初衷,建议缩小互测所占比例。
posted @ 2021-06-22 11:15  不会写代码的工科狗  阅读(62)  评论(0)    收藏  举报