BUAA_OO(2020)_Unit4_Summary

一、第四单元三次作业架构设计总结

第四单元的三次作业架构设计上,基本就是对官方包中的所有模型元素类(UMLElement)进行了代理,从而方便存储额外的信息来实现一些查找检测,然后各种暴力遍历解决问题,主要内容在于初始化后MyUmlElement添加保存所有的子元素以及MyUmlClass,MyUmlInterface添加保存各种关系的对端(继承关系的父子、实现的接口、关联的对端等)以及属性和方法,出于懒的原因,普通状态、初始状态、结束状态既不是像官方包各自独立也没有采用继承层次关系,而是都由MyUmlState代理,仅在内部加标志位以区分,在这个简化的模型中由于初始和结束没有体现出太大的特殊性因此实现起来还比较容易,MyUmlState添加记录了所有前导和后继状态,最后是MyUmlLifeLine添加记录了所有的进入和发出消息,在此基础上各个查询方法能够很容易的沿着任何关系网完成遍历,从而实现各种查找。

二、四个单元中架构设计及OO方法理解的演进总结

第一单元第一次作业的时候因为内容很简单加上刚开始面向对象编程,基本还处于直接莽的状态,随后第二次作业就感到压力较大了,显然需要优化代码结构,于是进行重构,二三次作业的设计主要借鉴sympy源码的架构设计来规划,因此整体结构逻辑上还是比较简洁清晰的,但是受限自己面向对象编程功力还远不足,具体的实现与功能划分上存在混乱,代码结构有不少冗余杂乱的部分,对设计模式也没有很好的利用,细节上的结构不合理逐步影响整体,到了第三次作业的时候虽然没有出错误,但是进一步迭代的空间已经不多了。

第二单元开始了多线程,刚看完并尝试一些网络编程的内容加上接触到微服务设计等思路导致脑子一抽决定将这次作业的不同线程之间朝着能够分别在不同机器上同时运行并采用异步通信方式合作的架构设计,结果意外发现走上了较为轻松的道路,完全避免了显式锁的使用与内存安全的问题,并且电梯模拟并不设计大量数据的处理,复制、传递以及冗余数据带来的开销可以忽略不计,电梯与调度器管理好各自的数据并通过唯一的一条消息队列进行交流似乎对对象这个概念有了更好的诠释。同时采用Strategy模式设计调度,并且借助工厂模式、观察者模式等多种思想进行设计,最终形成了有着不错可读性、扩展性的代码,体会到了设计模式的运用有着巨大的帮助。

三、四单元主要在于理解并体会给定的设计,学习JML和UML,以及测试相关内容,对自己的架构设计要求不高。

第三单元由于是按JML规格实现方法,没有太多的可设计空间,于是打开了偷懒的大门,基本全程就是照着JML实现,没有设计内容,当然第三次作业的时候对算法有一定的要求于是去补习补习了算法内容。

第四单元则基本是理解好题目要求,代理完给定元素,存好各种各样的关系网之后跑遍历就行了,对异常的使用能感受到采用抛出异常、捕获处理的方式确实比采用特定的返回值以及一些其他的方式处理错误数据要方便很多。

三、四个单元中测试理解和实践演进

测试方法按照课程引导方向应该是四个单元逐步从手捏数据手动输入到加上写评测机黑盒测试再到加上Junit白盒测试,逐步理解了测试的重要性以及多方面的测试方法,然而实践上我只是写了一个评测机从头用到尾,感觉上Junit一类的白盒测试即把程序整体拆开来对一个个组件进行测试,比起黑盒测试的优势在于对组件的测试往往更容易实现、更精确。然而这些优势在第三单元的设计中并不能体现出来,首先第三单元基本采用三四个类就能够完成实现,组件数少,并且用户接口处的输入输出采取指令的形式,一条指令唯一对应着一个函数的调用,调用层次浅,并能得到即时反馈,(可能是为了方便课程组的评测机测试)这导致白盒与黑盒的效果没什么区别,写一个测试类调用某个方法然后获取返回状态判断正误,和输入一条指令检测输出的效果是完全一致的,而直接使用黑盒测试的优点在于可以直接采取通用的评测脚本,构造或生成样例之后运行即可,而Junit需要针对性的写一系列代码浪费时间,所以第三单元还是采取了黑盒测试的方式。相比之下,第一单元的作业对白盒测试的优点可以有更好的体现,第一单元的用户接口表现为输入一个表达式,输出为求导并优化的结果,其中至少要经历字符串解析、表达式求导、表达式化简等一系列步骤,每个步骤可能还被拆分为了一系列类和方法的协作,此时中间某个方法的效果很难直接体现在输出结果中,甚至可能某些方法是错误的最终还给出了正确的结果,即使发现结果错误也很难定位问题出在什么方法上,因此逐个类逐个方法进行测试很有效果。(然而第一单元时还完全不知道单元测试这回事)第二单元的测试比较特殊,因为答案不唯一,只需要验证答案符合给出的规则(不变式)即可,相对来说是比较容易测试的,因为验证答案是否符合规则的程序是很容易实现的,属于验证比得出容易很多的一类问题,可以认为不会写错验证程序,所以任何样例输入,不需要标程的协助都可以拿来直接测试。而其他三个单元属于验证和得出答案难度一样的问题,都面临着测试中的最大问题,正确结果是什么,不论白盒还是黑盒测试,都必须知道代码(程序整体或者某个部件)运行的预期结果是什么,然而依靠人脑构造样例与答案很大程度上面临自己测自己的问题,即能够想到的特殊情况,那肯定会在程序中进行处理,漏掉处理的情况,自己也很难会想到相应的样例,而依赖机器随机(亦或增加一些针对性)地生成样例必然不可能依赖人脑去获取正确结果,因此需要标程来计算正确答案,第一单元还可以依赖sympy取巧获取答案,第三、四单元则很难做到了,因此自己进行测试在整个开发过程中起到的更多作用似乎还是回归测试的效果,很多时候是开发过程中每想到一种特殊情况就添加一组样例(一组给脚本的输入数据或者一段Junit代码),初步完成程序的时候几乎肯定能通过所有的测试数据,因为这些数据就是自己开发时设计出来的,随后的功能增加或者优化过程中不断地重新测试,就能保证后续的修改不会造成本来已经考虑到了情况出现错误。

四、课程收获

进一步熟悉了Java语言的使用,学习了面向对象编程的思想,并且第一次接触了并发程序设计,掌握了一些并发程序设计中要考虑的问题与解决技巧,学会了一系列的设计模式,体会到了在编程中运用设计模式对设计思考量、编程难度、可扩展性的改善,初步了解了JML的作用与使用方法以及UML的结构(虽然还没有体会到其好处)

五、课程建议

  1. 第三单元教学内容:第三单元问题在于JML本身的发展并不完善,无论是语法还是工具链都显得粗糙,没有完整的工具体系就相当于在用记事本写代码,即使是课程组写的代码也难免存在小问题,而且说实话JML叫Java Modeling Language然而就课程学到的这些部分并没有看出它和Java联系在哪里,它貌似只具有最基本的形式化描述语法,而这些语法用到任何编程语言上都没啥区别,同时其它的形式化描述语言也都有这些语法功能。JML可能作为研究方向还行,但作为大二课程教学内容会使得学生感到学的东西乱七八糟不成体系。并且可能因此课程中并没有安排学生写JML的内容,然而形式化描述本就是写起来才有难度,可以说这样一单元下来基本上什么都没学到。当然,还是复习了一下算法,不过如果说第三单元的目的是学算法的话显然与课程内容完全不符。可以理解第三单元教学面临的困难,因为貌似目前形式化验证还处在研究阶段,工业化基本没有实现,没有能完善得像JAVA的IDE一样的形式化描述IDE。可以考虑要么把JML的内容部分边缘化,目前这种强行把JML中心化的方式导致第三单元的中心直接没东西了,把JML作为一个小内容提一提,在第三单元加入其它的教学内容可能会更好,要么给JML的教学添上足够的内容,让学生能够充分体验写JML、用JML的过程,能真正体会JML的好处。
  2. 单元测试教学的安排:正如上面有关测试的部分说的,单元测试在第三单元开始加入教学,但是三、四单元都非常简单,组件少、层次浅,在用户IO接口直接反映出了程序内部状况,完全体现不出单元测试小粒度的优点,可以考虑将单元测试的引入提前,作为帮助学生解决一、二单元问题的工具,或者在第三单元加入更复杂的程序使得程序有充分多的隐藏在系统内部的类与方法。
  3. 实验课:不太清楚实验课在课程中是作为什么地位存在的,如果作为考核的话,显得很粗糙简单,时不时还出些问题,如果作为教学的话,没有反馈的机制基本上什么都学不到,可以考虑做得更完善并予以适当的反馈。

六、线上学习OO课程体会

OO课程可能是受线上教学影响最小的一门课了吧,因为OO课程的核心内容在于通过作业去体会OO思想和其他教学内容,在运用理论课知识解决问题的过程中理解理论的内容与作用,网课的方式对我学习理论知识来说感觉没什么影响,并且线上作业和实验等于没有受到任何影响,总的来说,线上学习OO课程的体验还是很棒的。

你可能感兴趣的:(BUAA_OO(2020)_Unit4_Summary)