OO-第四单元总结
一、总结本单元两次作业架构设计
1.UML第一次作业
本次作业中使用的是将类图抽象为一个TrueClass对象,用来存储类中的相关信息,在TrueClass中还创建了方法对象Oper,属性对象Attribute,还有用来存储查找的中间变量AfterCal用来实现记忆查找,在Oper对象中还创建了传入的参数对象,总体来说就是进行了分层次的存储,并且使用新建的对象AfterCal来记忆计算过的结果,减少需要进行的从头查找的次数(但是在运行时间上表现并没有比不进行记忆存储好很多。。。。。。)查找时的方法是使用了递归,是为了能够进行记忆搜索,将“路过”的类的结果也记录下来。感觉上由于使用的层次较多,出现问题时比较容易定位,Debug体验很良好。在强测中没有发现问题。本次UML类图如下

2. UML第二次作业
本次作业的解析类图的部分是通过继承上次作业实现的,解析状态图的部分是通过创建状态图类State的Hashmap实现的,在State中存有region,用以对应region, 还有状态迁移的Arraylist,其中存的是迁移到的state的id;解析顺序图的部分同理,是创建Interaction,然后在Interaction中存有messcnt用来记录不同的message,并且存有lifes用来记录生命线,lifel是生命线类,用来存生命线中的元素。本次的算法主要是检查有效性的部分,主要是使用了类似bfs的写法,实际上在查是否有循环继承时写了bug,由于在将某个类的继承的类及接口加入暂时循环使用的队列时未考虑是否已经遍历过这个类了导致了死循环。并且在添加Messege时没有考虑target找不到的情况,导致了抛出异常。本次的类图如下。
二、在四个单元中架构设计及OO方法理解的演进
在第一单元时实际上并没有很好的理解面向对象的思想,总体还是使用C语言的面向过程的写法,导致代码比较长,而且维护起来难度较大,出现问题难以定位。在第一单元的前两次作业中没有用到面向对象的思想。在最后一次作业中为了能够拆分多项式并分别处理,使用了一点点面向对象的思想,即将多项式通过符号逐步拆分,并对拆分出的字符串进行递归的处理,如果是能够处理的简单项则进行求导,然后进行乘法,加法,如果不是简单项则加入初始的类中进行处理。
在第二单元时对面向对象有了初步的理解,能够简单地运用。但是第一次作业由于对多线程的理解是错误的,自己理解的是每一条指令作为一个线程,虽然在本次作业没有出现问题,但是我认为如果数据量庞大,会引起很大问题。第二作业由于对调度器理解有误翻车,导致写了一次无效作业。但是后来改正后发现也不是很大的问题,只是很小的地方没有处理好线程问题的冲突。第二次作业修改后的架构是由调度器将乘客塞给电梯,电梯自己只负责运行,运行完毕至车内无人则等待调度器发出指令。第三次作业我一开始的想法有些复杂。开始时试图沿用上一次的策略,电梯每到一层,由调度器将能够上电梯的人塞入电梯,但是这次由于有三种电梯,且如果这样写的话换乘电梯较为复杂,所以最后并没有成功实现。后来的做法是,有三个电梯线程,一个调度器线程,一个输入线程。电梯负责将本电梯的等待队列捎带进入电梯,调度器负责将能直达的指令塞给电梯的等待队列,将无法直达的指令通过计算出两层间能够从哪层换乘其他电梯来拆分指令,并分为两部分塞入电梯和存入乘客类的副指令中,在人出电梯时才将副指令加入指令队列中。这种调度虽然无法让其他电梯在能够接人时提前过去,但是在最大限度上保证了线程安全,最后在强测及互测中正确性表现良好。
在第三单元时对面向对象的思想能够正确运用了,并且使用了继承的做法(之前由于checkstyle会报错导致基本没有使用)。在第一次作业就是按照JML进行书写,申请了三个HashMap,plist,pidlist,和dot。plist中使用路径的Id作为key,用来存储路径;pidlist使用的是path转为字符串作为Key,用来存储路径对应的Id;dot用结点Id作为key,用来存储点的个数。其中为了减少查找不同点的复杂度,每次addPath的时候都会进行点集合(dot)的增加,每次remove时也会对dot进行修改,使查找不同点方法的复杂度降为O(1)。在第二次作业中当时由于checkstyle在继承时父类中如果又public属性会导致无法通过,就没有使用继承,而是直接将上次的代码复制粘贴到了本次作业,导致代码较为臃肿。在本次作业中使用了两个hashmap来对应点和抽象数组的关系,这样能够做到在一个120*120的图中进行运算,效果比较好。每次在有add和remove指令时重新计算两个最短路径图和可达矩阵,这样能够降低些查找的复杂度。在本单元的第三次作业中,使用了继承上次的作业,就是并未修改父类的对象,而是在子类中使用super获取父类的对象。这样能够在checkstyle不报错的前提下使用继承。在作业中使用了不拆点的做法,将所有点映射到大小为120*120的二维数组中,能够较为便捷的计算。在上次的基础上新增了用来存储最低票价,最少换乘,最低不满意度的二维数组。每次add时重新计算这三个矩阵。但是由于算法的问题,每次remove时需要将所有路径重新添加,并计算每一条,这样能够直接将换乘的代价加入,较为简便。但是这样写也就牺牲了增加和删除路径时的不满意度。
在第四单元也就是最后的本单元,能够正常运用面向对象的思想了。(通过类图的复杂程度可见。。。架构主要是建立各种类,用来分层次存储所需的数据,维护起来较为方便。
三、在四个单元中测试理解与实践的演进
在第一个单元中主要使用的是自己手动构造各种测试用例,效果不佳,覆盖面也不够广。
在第二个单元中使用过通过C语言进行简单的输出作为测试用例,虽然比较极限但是数据面也不够广,测试效果不是很好。输入时使用了按键精灵来完成定时的输入。
在第三个单元中也是使用了通过C语言进行简单的输出作为测试用例,能够较好地测试极端情况,但是随机性不太好。
在第四个单元中使用的是手动画UML图,并使用官方的工具进行解析,进行测试。较为直观。
四、课程收获
OO这门课对我来说是受益匪浅的。首先是每周的时间线,虽然整周都较为紧张,但是在完成任务后也是成就感满满。也培养了自己的抗压能力。。在每单元作业的递进式的难度中,能够较好地理解本单元的重点,并且对面向对象的思想的理解也是逐步加深的。还锻炼了自己的心理素质。第二单元第二次作业翻车后感觉实际上当时如果心态放平还是有可能改对的(毕竟在修复bug是大概只是看了20多分钟就找到了问题所在)虽然第二单元第三次作业一开始写的架构较为复杂导致实现难度较高,但是认识到问题后冷静开始重构,最后效果还是可以的。代码风格的检查也使我现在敲代码会向标准的格式靠拢,(从修改代码格式的时长可以看出)每次作业修改的都在变少。
五、立足于自己的体会给课程提三个具体改进建议
1. 线程单元我认为是可以在第一次作业时给一些提示,或者标准的有关线程的代码。我开始对多线程理解的错误实际上是源自一次实验,实验中所给的代码是银行柜台排队的问题,其中就是每次来一个请求就开一个线程,于是当时我对多线程的理解就是每个请求是一个线程。这样实际上是比较浪费资源的,所以我认为在开始时可以做一些代码方面的引导。
2. 实验课与理论课我认为间隔较少,是否能够在本周做上周理论课讲的内容,这样能够留出时间进行理解。
3. 能否多提供一些标准写法的有关架构实现的代码,老师们在课上强调了多次架构的重要性,但是对我而言架构的实现有些困难。希望能够提供标准写法的代码以供参考。
浙公网安备 33010602011771号