面向对象设计与构造第四单元总结及期终总结
1、总结本单元两次作业的架构设计
仍然从类图的角度对架构加以说明
(1)第一次作业
图一 第一次作业类图
本单元的任务是解析uml图,第一次作业是对于类图的解析,并且实现对于类图的查询功能。可以看到为了实现对于类图的存储,我们在程序内部要对uml的结构进行模仿。首先类图的主体架构是类和接口,而类和接口的很多性质是类似的,比如都有属性,操作以及继承关系等等,又有很多不同,比如接口可以多继承而类不可以,类可以实现接口,而接口不可以实现接口。因此在架构上设置Node这个抽象类,在抽象类中实现类和接口共有的一些功能。而Javaclass和JavaInte则是继承了Node接口,分别表示类和接口。并且以类和接口作为容器,实现对于类图其他元素,包括类的属性、类的操作、类的继承关系、类的关联关系等等。并且在类和接口的容器中实现对于类或者接口的查询方法。本次架构的一个优势就是把类和接口统一处理,为之后作业对于继承实现关系的处理或者检测打下伏笔。一个缺点就是所有的前期处理都放在了MyUmlInteraction类中实现,没有分级分类处理,代码过于冗长,不利于扩充,为之后加入时序图和状态图留下了隐患。
(2)第二次作业
图二 第二次作业类图
本次作业基本沿用了上一次的架构,也可以说是本学期所有作业中沿用上一次作业架构最多的一次(当然还有一个原因就是考期比较忙,有一些地方虽然架构并不合理,但由于时间紧张也就稍微“得过且过了”),本次作业类图和接口的处理完全和上一次一样,不重复介绍。对于状态图和顺序图的查询则是建立两个类分别存储状态图的transition信息以及顺序图的message信息。对于三条检查则是建立了一个单例模式的Check类,在不同的处理过程以及查询过程中获取该类的引用,类记录检测状态。本次架构上的一个缺陷就是由于上一次作业遗留的前期处理扎堆问题,导致这一次MyUmlInteraction类超出限制,只好把一部分处理单独放在了另一个Seqstate类中,换句话说Seqstate类的设置完全是代码的一个转移并没有经过架构设计上的考虑。
2、总结自己在四个单元中架构设计及OO方法理解的演进
(1)总结架构设计
第一单元:这一单元是OO刚入手的一个单元,第一次作业基本没有涉及到有关架构的问题,因为需要处理的多项式十分简单,没有太多的层次的关系,然而随着多项式复杂度的不断加大,架构的设计就显得非常重要了,我在第三次作业中由于涉及到了多项式的嵌套,所以总体架构我选择了有递归特点的二叉树结构,与表达式树类似,我把每一个每一种运算比如加、减、乘、复合等运算作为内部节点,把每一个单项作为叶子节点,对每一个运算定义求导规则,求导的时候自上向下递归求导。
第二单元:这一单元的重点是引入了多线程,我的基本设计模式便是生产者消费者模式,输入线程把一个请求放入一个托盘,电梯线程把请求从托盘中取出进行处理。这一单元设计的设计架构主要体现在最后一次多电梯上。我的设计模式是每一个电梯有着自己的托盘,各个电梯互不干扰,主调度器根据一定的策略把请求放入指定电梯的托盘之中,电梯按照look算法对请求进行处理。这样尽可能地降低耦合程度防止出现有关线程安全的bug(尽管还是出现了)。
第三单元:这一单元的前两次作业基本上架构非常简单,只需要实现一些简单的数据机构以及求得最短路径的算法即可。第三次作业则需要在架构上加以考虑了,首先我把四个主体功能分开单独建模求得最短路径、最短换乘、最低票价以及对少不满意度。地铁系统把输入的path传给各个模型,各个模型内部根据相应的算法进行求解,并且在查询的时候将结果返回给地铁系统。
(第四单元的架构不重复叙述)
(2)OO方法理解的演进
随着作业的不断推进,对于OO的理解也在不断地从浅到深,从具体到抽象。在第一单元我们知道了可以把一个多项式的项以及一个多项式抽象为一个对象,这还是在一个十分具体的场景。第二单元我们知道了一个线程也是一个对象,不同对象之间可以并发的工作。再到第三单元,我么知道了可以把一个数据结构及其中的算法封装成一个对象,最后一个单元我们知道了一个对象是由哪些基本元素组成,这些元素又是依据什么规则组成的对象。
3、总结自己在四个单元中测试理解与实践的演进
第一单元是对于测试的理解突破最大的一个单元,即引入了自动化测试。由于OO作业需要实现的功能相对较复杂,情况种类千奇百怪,想要手工测试基本不太可能,因此我开始尝试写自动生成测试用例的脚本,并通过matlab等工具实现评测。到了第二个单元我发现了在本地测试不出来的问题,在评测服务器上就会出现,我开始注意到评测结果是与本机的环境有关的。第三单元测试的难点就是如何把各种情况都考虑到,就此引入了单元测试,以此来进行覆盖性的测试。第四单元测试的一个最大的一个调参挑战就是生成合法的测试用例,因为测试用例必须要符合Java8标准。
在这学期的测试中我有两点收获
(1)测试的难点有两个方面,以方面是数据生成,比如第一单元的作业,测试非常简单只需要利用matlab或者python 的sympy包就可以完成,当时需要构造完备的测试用例,另一个方面就是评测正确性,比如第二单元,这一单元的测试用例生成十分简单,只需要随机生成请求即可,但是判断正确性就十分的麻烦,因为这个结果是不唯一的,只要合理即可。
(2)另一个问题就是测试需要考虑到多种情况,而且在编写测试用例生成脚本的时候不能按照自己写作业的思路写,那样很多问题是发现不了的。比如我在和我一个同学对拍的时候,他有一个问题就是他在判断两个个点是否连接的时候没有事先判断这个点是否存在,但是由于我我认为这个判断是理所应当的,因此我在生成测试用例的时候选择的所有点都是从已有点里选择的,结果就没有发现他的bug,最终造成了他强测失分。
4、总结自己的课程收获
“面向对象设计与构造”从名字看起来一门非常普通的一门课学起来却是要付出巨大的努力。可以说这门课占用了我这学期所有的周末。但我认为这样的付出是值得的。
(1)通过这样一门课程的学习,编程能力得到了提高。我认为编程能力就是把一个设计模式或者设计思路用程序正确地表达出来的能力。这个能力的提高绝对不是纸上谈兵可以实现的,必须经过大量实践,我认为OO这门课程的确提高了这方面的能力。
(2)我对于面向对象这种设计模式有了深入的理解,之前学习程序设计都是基于如何设计一个流程来解决我的问题,通过面向对象的学习我知道了在设计之前第一步便是确立需要哪些对象。
(3)对于“架构”这个概念有了一定的认识,之前写C语言或者python程序基本都是实现一个非常简单的功能,一般的做法就是把所有的功能全部放在主函数里面,根本没有架构可言,然而OO作业中实现的功能就必须要有一个合适的架构来保证,否则可能连基本功能都实现不了。
(4)掌握了一些测试的基本方法,之前的编程其实是把测试的任务留给了老师,自己编完程序就直接提交,有问题再改,再提交什么时候通过什么时候为止,OO这门课的测试模式就要求我们必须要掌握一定的测试方法。
5、立足于自己的体会给课程提三个具体改进建议
(1)合理设置难度梯度,这四个单元中第二单元和第四单元的难度梯度设置比较合理,但是第一单元和第三单元的最后一次作业难度突增,要远远超过前两次作业。
(2)适当增加中测强度,第一单元和第四单元中的中测设置的比较合理,对程序的鲁棒性进行了较为全面的测试,但是第二和第三单元的中测强度过弱,有可能导致一个非常细小的问题导致强测全部“爆炸”,可能会使已经正确实现的功能功亏一篑。
(3)在指导书无法明确描述的时候尽可能多第给出样例。比如第四单元的作业确实一些问题指导书是不太可能详细地描述出来,换句话说就是描述的再详细,也会有一定的分歧,因此在一些不太好描述的地方应该给出充分的样例,样例至少应该覆盖各种输出情况。