第四单元总结

第四单元总结

  • 本单元架构设计
     在本单元中,我并没有设计很好的架构,整体的实现思路完全是直接而线性的,这主要是因为本单元数据量并不大,所以可以通过考虑每一个方法的实现来解决所有的指令需求。
     在具体实现方面,我这样的设计并没有什么特殊之处,仅仅就是兵来将挡,水来土掩,有什么需求就加什么功能罢了。
     这里举几个例子来说明。
     第一次作业的计算属性的耦合度就依赖于遍历所有元素的数组进行递归的实现,每一次计算本级然后递归计算上一级。
     第二次作业的判断关键状态,核心思路是bfs,但实现上依旧是依靠遍历,获得点与点之间的关系,然后进行判断。
     第三次作业检查循环继承,我使用的算法也是bfs,通过一次次遍历来进行路径探索。
     不难看出,上述实现中出现最多的词语就是遍历,更直白的一点来说,这个单元我的作业里其实没有什么架构,只有粗暴的实现。
     那么,就让我来对比一下这样的暴力实现和前几单元通过设计架构实现的区别。
     最能突出架构设计的可能是第一单元,在第一单元里,我做了很多层次化的设计,考虑了数据如何组织才能更加高效,每一个顶层调用底层的方法来实现相应的功能,整个体系相互协同。
     然而即使进行对比,我也不能说第一单元的代码远远优于第四单元的代码。我一直在其中思索,但更在其中迷茫,当我把第一单元的代码和第四单元的代码放在一起时,我开始考虑一个我从未想明白的问题——什么是OO。
     即使经过了一个学期的学习,我也很难给OO下一个定义,而网上的定义也让我觉得站不住脚。
    OO就是基于对象概念,以对象为中心,以类和继承为构造机制,充分利用接口和多态提供灵活性,来认识、理解、刻划客观世界和设计、构建相应的软件系统。
     如果这就是OO,那OO未免太廉价了,只要使用java语言写出的代码就是面向对象的吗?
     回到最初的比较,第一单元的代码是分了相当多的类,是干了很多的层次化,是利用了接口和多态,但本质上和第四单元的代码有什么区别。从一个极端的角度来看,如果用C写,那些功能照样可以实现,只需要把那些函数从类里面拿出来,按照功能顺序全部排列下来就可以了,真正阻碍使用C来实现的是hashMap,hashSet这些java提供的非常好用的包。
     抽象不能掩盖本质,第一单元最难的不是使用OO(我们姑且以上面的定义来定义它),而是实现的思路。这样的多项式求解让没有经过足够的编程训练的我们无所适从。但仅仅是OO的机制和java的特性,我并不认为那是北航的学生会觉得复杂的,而且很容易看出,在第一单元做得好的人多是编程的大佬而非理论研究的大佬。
     所以我有一些不成熟的观点,就我的理解,java的机制似乎只是让编程更加清晰。类内部维护自己的属性,而不需要我们去负责修改。类一定会提供一个与描述一样的方法,而不需要我们去顾虑。无可置疑这些都让编程更加得容易。
     但我真正想理解的是本质,使用OO的设计(第一单元)和暴力的直接的考虑(第四单元)本质区别在哪里?即使我在第四单元构建了图,我感觉自己的构图方式只是把那些分开的方法合在了一个类里,然后在分开的方法里调用图的属性而已。
     很明显,这样思索必然会走向一个永不可解的极端,毕竟计算机的科学里面一切也只是抽象。一定要说的话,用C语言都可以实现java,如果只是不断从源头上靠,最终会毫无成果。
     在马原课上,一位同学的读书报告让我有了一些新的体会————理论是无上限的,但实际才是根基。任何的社会问题,你似乎都可以占在任何一方,任何一方你都有可持的理论。但奇怪的是总有人能有更高明,更难以反驳的理论。
     所以当我以这样的心态再去看代码的时候,我不得不承认第四单元如果按照构图来写,代码量和思考难度都会降低,第一单元如果使用纯分析的方式去写,也会复杂很多,需要考虑多种情况。所以既然这样的方式能够更好地解决问题,为什么一定要纠结于它的定义和本质区别呢。
     码无定法,一切都由需求而定,什么样的方式能更好地实现需求,能更方便地进行迭代,能更轻松地维护,它就应该被使用。就如OO的设计模式,也可以进行自己的改良和删减,这些设计模式传达的是一种理念和思路,编程时应该抓住思想的高度,而非具体的模板。
  • 架构设计思维和OO方法演进
     在完成OO作业的过程中,我的架构设计能力确实在不断提升,在第一单元的设计中,我进行了一次大的重构,但在之后的单元里我基本没有再进行重构。
     这背后其实是我的思维方式的转换,从直白的过程和算法到考虑一个体系的设计,这其中也有co和os的一些帮助。在设计一个体系的时候,最重要的是想好体系的组成和功能,而不用纠结于具体的实现。比如第一单元里,可以把构架考虑成输入解析,计算解析,输出优化三个小部件,而这些部件具体的实现又可以利用这样的方式进行推演,由顶层到底层逐步细化,再由底层到顶层完全实现。第二单元里就可以考虑不同的主体,电梯,调度器,输入器,再去考虑这些主体如何联动。
     除了体系的组成和功能,另一个关键的细节是可拓展性。做好代码的可拓展性是相当考验能力的一件事,我并没有很系统的方案去解决这个问题,但是也有一些经验。
    • 将功能合理扩大,用更强的需求写代码
      • 在第一单元第一次作业里,我就考虑了未来加除法的可能性,并设计了一整套除法有关的方法,可惜作业并没有要求这一点,这也是我重构的一个原因吧。
      • 在第三单元里,我也考虑了存储路径的可能需求,并将其实现
    • 注意方法的原子性
      • 这里的原子指的是最小单元性,比如第一单元里,涉及到不同元素之间的运算,在每一次编程时,都应该把运算的类型写明白。
      • 原子性的实现也会让方法有更好的复用性。
  • 在四个单元中测试理解与实践的展示
     bug是OO课程里最讨厌的事情,而想要减少bug,测试就必不可少,那么如何进行测试?
     我在四个单元里并没有特别关注于互测,只是进行了很多自测。从我的经验来看,使用自动测试是一种简单但不够强大的测试,我在自测的时候更多传承了计组的测试思路,进行基本功能测试和模块测试。
     我这样的测试思路大部分时候必须要依赖于读代码,必须通过代码来确认最小的测试元,然后进行最基本的元的测试。
     这种测试的优点是比较全面,能排除绝大多数的常见bug。但缺点同样明显:测试非常费时间、互测时不可使用而且会由于自己的惯性思维忽视掉一些可能的细微的bug,我就因此在电梯留了一个以为不可能出现的bug。
     在听同学的分享时,我觉得还是要将代码测试和自动化测试结合起来,所以第三单元采取了二者的结合,第四单元并没有做很多测试,主要是在编程的时候争取bugfree。
  • 课程收获
    • 熟悉并掌握了java基本语法和常用的数据结构包
    • 对JML建模语言和UML建模工具有了一定的了解,可以在此基础上实现项目架构
    • 极大提升了编程能力和测试能力
    • 初步了解了OO的设计理念和设计思想
  • 建议
    • 调整课程顺序,初学的时候对于Java语言的特性不甚明了,而第一单元总体难度较大,可以把一三单元调换位置,方便学生进行过渡。
    • 在第三、四单元适度调高中测强度,第三四单元主要的教学目标是了解并应用jml和UML,如果中测过弱,并不能起到很好的教学效果,可能没费太多力气就写好了代码,但强测出现过多问题。
    • 尝试设计一种更开放的讨论区,在计组课程中讨论区的帖子往往有着很多的资源和非常有价值的设计思路。在OO互测的背景下,OO的讨论区没有特别好和特别实用的资源。当然从课程考核调度来看,OO是平时考核,强调独立完成也没什么不妥,毕竟co是要进行上机,课下的独立性没有掌握能力重要。
posted @ 2022-06-28 17:36  20373kai  阅读(18)  评论(0编辑  收藏  举报