第四次单元总结
本单元架构设计总结
第一次作业:类图解析
本次作业仅仅需要实现官方的UmlInteraction接口,通过反射机制在Runner中实例化一个我们实现的类,来进行类图元素的分类解析,从而完成接口所要求的元素的查找功能。
第二次作业:增加顺序图、状态图的解析
本次作业需要实现官方的UmlGeneralInteraction接口,对于UmlGeneralInteraction接口,又继承了UmlClassModelInteraction, UmlCollaborationInteraction, UmlStateChartInteraction三个接口,因此在设计时最好使用适配器模式,先实现三种UML图的类,接着,在实现UmlGeneralInteraction接口的类中实例化这三个基本类,我们可以通过简单的调用相应类的方法来满足接口方法的实现要求。但是个人在实现时直接在MyUmlGeneralInteraction类中完成了三种图的解析,也是稍稍摸了一手鱼。
第三次作业:UML图规则检查
本次作业继续实现官方的UmlGeneralInteraction接口,除了上次的UmlClassModelInteraction, UmlCollaborationInteraction, UmlStateChartInteraction三个接口,又增加了UmlStandardPreCheck接口,对于如此庞大的组合,不得不重新设计架构。最终实现了四个基础接口,来满足UmlGeneralInteraction接口的需求,同时,元素分类和结构树建立的部分可以成为独立的一部分,因此建立了MyAnalyse类将这一部分功能进行封装,同时,这样也便于被分开的四组图的查询类中方法可能需要分类中产生的一些容器信息,将MyAnalyse设计为单例模式,或仅仅简单的传参给其他类的构造器,都能很好的达到目的。
四个单元架构设计总结及OO方法理解演进
Unit 1
第一单元我们进行了多项式求导的迭代开发,从简单的x加减乘除平方,到sinx、cosx,以及复合函数的跟进,让我们的架构一步步复杂起来,从最初的仅仅是一个以x为基本组成的类,到拥有多种函数、甚至是复合函数的多项式组合,难度一层又一层的递进着。
这次作业最大的困难困难在于架构的设计和迭代,由于不知道下一次作业到底有着怎样的要求,我们为后面的功能迭代需要留下的扩展就不容易掌控,在迭代中,我也经历过几次重构,十分痛苦。除了首次接触架构设计的经验不足和考虑不周产生的诸多问题,对表达式的解析,尤其是regex的使用和指导书的形式化表达的多项式有效形式的说明,都让我头痛不已。
这次作业我构造了Power、Sin、Cos这三个类,他们都实现了接口Item,作为一个多项式的基本元素,第二层是Func类,他是Item的元素的乘或除法运算组成的多项式,第三层是Poly,他是Func的加或减法运算组成的多项式,依靠他们,完成了整个多项式信息的存储以及求导的计算。这种结构即保证了数据的层次化,也使得各个类保持低耦合性。
Unit 2
第二单元主要进行多线程电梯调度问题,这次作业除了对调度算法进行设计,更多的问题在于多线程之间共享资源可能产生的错误,为了设计出线程安全的程序,我们使用了生产消费者模型、甚至是流水线模型来实现多电梯的调度模块。
在本单元最后一次作业中,需要实现多种电梯的调度,并且加入新增电梯的指令,代码中的共享容器很多,需要我们精心的设计,以免出现资源竞争、死锁等问题。设计了一个输入线程模块、一个总的乘客调度模块,还有各个电梯线程模块,这样保证了输入与运行的并行性,也使得乘客的调度变得简单,我将对乘客进入电梯的选择和电梯运行中动作的选择分离开,在局部中寻找更加合适的调度方法,而不是统筹考虑全局,让算法的实现更加简单。同时,这种设计也可以避免过多共享资源导致我们不能很好判断资源是否被我们锁住,或者产生死锁的可能。
Unit 3
第三单元是关于JML形式化语言的单元,主要通过形式化语言的描述,完成了对一个社交网络的模拟程序。形式化语言保证了我们实现的方法的功能的正确性,避免了自然语言中所蕴含的多义性问题,JML通过在行为层面规范我们的设计,来保证程序的正确性,但是,JML相关工具链并不十分完善,且具有诸多bug,在使用时暂时不是很有作用。
此次作业主要为根据JML实现正确的方法,以及一些图的算法,架构层面考虑的不多。
Unit 4
第四单元主要根据UML的类图、顺序图、状态图相关结构,将所给元素进行分析组合,以实现官方所给的接口中的相关方法。官方接口以一定次序继承了一些图相关的接口,这让我们能够很清晰的分离开各个类的解析部分和查询部分,因此,这次作业在迭代和架构设计中都十分容易,也能设计出漂亮的结构来,具体架构见上节。
四个单元测试理解与实践的演进
oo初始,仅仅延续以往C语言程序设计和数据结构中所使用的方法,依据评测机进行程序的测试,在整个课程的预习阶段,都是查看评测机所给的反馈,再次进行程序bug的排查。
进入第一单元,为了保证自己程序的正确性,以及在互测中轻松发现别人的bug,拿起了python开始编写自动化评测机,用随机大量的测试程序进行对拍,效果拔群。
到了第三单元,随机数据既不好生成,也没有真正正确的答案可以对拍了,我们不得不构造一些特殊的数据进行定点爆破,在这些数据中,一次又一次的更换测试数据进行回归测试不仅费时费力,也不够科学,因此,使用了JUint进行单元测试,在测试之后,还能查看语句的覆盖程度,让我们更科学的进行测试。
OO四个单元的测试,不单单是个人的功劳,是有着许许多多同学的互相帮助,才能够获得不同的测试点,更好用的评测机,也有许许多多的启发来自他们,可以说,测试让我体会了到协作开发的快乐。
课程收获
通过四个单元的学习与代码编写,逐渐了解到面向对象这种设计方法的美妙之处,它不同于过程型语言的编写,OO以类为单位进行封装和设计,我们对每个不同的类设计它的属性和方法,使得每个类都能够描述一种对应的物体和这个物体具有的功能或行为,整个程序的运行不是过程型那样,只是遵循一条语句的顺序执行,以及函数的层层调用,而OO则是将不同的类及他们的实例组合起来,构造一个交互性的类的集合,从而完成程序功能的实现。
对于面向对象的设计,我们同时也了解到了工厂模式、适配器模式等诸多设计模式,也学习了生产者消费者模型等多线程模型,我们在每个单元的三次迭代中逐渐把握层次化的设计思路,让每一个类都能够在合理的架构设计中完善起来,接口的实现和类的继承,让我们代码具有极高的复用性,而良好的结构,也让我们代码易懂且便于维护。设计,让我们更像一位工程师,而不是码农。
同时,我也学习了JML形式化语言,了解到了这种形式化描述的方法在设计和代码实现中的作用,在UML图这个单元,也了解了各个图对于我们程序的描述有着不同且重要的意义。
在测试中,为了自动化,又不得不学习了Python语言,在编写评测机中,逐渐深入,更加了解了这种极具简单的美的语言。
对课程的建议
- 最大最大的疑惑,实验课的安排到底是为了什么,虽然每次的选题都真的很有意义,但是,不给反馈这一点不是很说得过去,每一次都做的稀里糊涂,不知所云。在后两个单元的实验中,更是有奇怪的感觉,不知道自己在干什么(笑哭),画画图?学学离散?谁知道额~,希望以后的实验能给同学们多一些反馈。
- 对于课程中安排的每周一次的作业,虽然确实有明显的在引导我们完成这个单元的主要任务,如架构设计、多线程设计、JML阅读、UML理解等,但是又在20%的程度上对算法进行考核,诚然,编程离不开算法,但算法方面弱的同学有些吃亏,且在这个内卷的社会,更多的看重算法的竞争,反而忽视了架构的设计(我是这样),希望能够合理减少算法考核,这真的很心累。
- 第三单元的JML似乎超越了这门课的学习范畴,一是没有什么需要思考的架构设计,仅仅是离散的再度学习,二是本身提供的工具链不够完善,工业界似乎也没有多少运用,学完后依然不太理解他的作用。
线上学习OO课程的体会
虽然没有经历过线下OO的学习,但线上OO确实没有影响到这个课程的进度或是学习体验,我们能够利用讨论区与同学和助教们讨论、提问、解答,能够利用gitlab、course课程平台轻松完成所有作业的资料获取、代码评测,虽然研讨课可能在线下会有不一样的体验,但对于我来说,能不露脸就不露脸,是一件极其愉快的事情。
真心感谢老师们、助教们的辛勤付出,这学期的OO课程真的很愉快。