• 【作业4.0】OO第四单元作业总结


    ------------恢复内容开始------------

    OO第四次总结

    总结本单元三次作业的架构设计

    类图

    第一次作业

    第二次作业

    第三次作业

    架构分析

    第一次作业

    本次作业的核心类为MyUMLInteraction,该类实现了UMLInteraction接口,完成了题目所述的功能。其他的类对UML类图进行解析,形成以MyClass类为核心的数据结构,方便以类名为查询入口进行查询。

    其他类有:MyParser、MyClass、MyInterface、MyOperation和主类Main。

    • 其中Main类只负责开启AppRunner线程,以及引入处理类MyUMLInteraction。
    • MyClass类为UMLClass类的扩展类,其中储存了该类的属性、方法、关联对象、父类、实现的接口等。为查询的基本数据结构。
    • MyInterface类为UMLInterface的扩展类,与MyClass类似,储存了该接口的方法、关联对象、父接口等。
    • MyOperation为UMLOperation的扩展类,储存了该方法的参数信息、返回值信息等。
    • MyParser类对原始数据进行解析,形成上述数据结构。

    对原始数据的解析是本次作业的重中之重,因此主要的代码逻辑在MyParser类中。该分以下步骤进行:对UMLElements进行分类,生成以id为key的HashMap。之后将所有的Attribute和Operation和和对应的MyClass进行关联,之后设置每个方法的参数和返回值,设置关联对象、父类、父接口和实现。

    public MyParser(UmlElement[] elements) {
        this.classify(elements);
        this.setAttributes();
        this.setOperations();
        this.setParams();
        this.setAssociations();
        this.setGeneralizations();
        this.setImplementations();
    }
    

    第二次作业

    第二次作业在第一次的基础上增加了关于时序图和状态图的补充,代码难度并没有上升,值得注意的是,本次作业的文件结构有一定的更新,文件结构的改善有利于各部分功能的平衡。

    第三次作业

    第三次作业增加了对于输入数据规范性的检查。值得注意的是,前两单元的数据都保证了本身的合理性,因此不需要对非法数据进行排除,只需要考虑极少部分的非法查询方式,而对于输入UML数据本身没有进行检查。

    本次作业若直接在1、2单元的基础上进行功能扩展,则会在解析数据时出现死循环等不可预料的问题,因此需要加强Parser类在解析数据时的鲁棒性。

    检查数据非法性的部分我放在了UML解析和输入数据处理二者之间,这样的好处是可以充分利用解析到的数据,缺点由上文所述,需要对解析数据的步骤做一些鲁棒性的改善。我将合法性检查的主要代码逻辑防在了对应的Parser类中,将合法性检查的结果使用缓存进行保存,这样的结构消耗内存较大,我们的作业对于空间的要求相比于时间要求而言相对宽松,因此使用缓存的设计相对理想。

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

    回顾四个单元,我的架构设计在多个维度上有了变化,我将分以下几个方面进行讲解。

    文件组织

    在寒假作业和第一单元作业时,我还完全没有掌握代码打包的方法,所有的文件都分散地放置在一个文件中。其实在第一、第二个单元的作业中,这样做的缺陷还不明显,因为类的数目相对比较少。而在后两个单元的作业中,这样做的问题则逐渐凸显。首先,各种类之间的逻辑功能有很多相互合作和相似之处,散乱的文件布局和相似的名字(很多以My开头的代码)很容易让我们混淆各个类之间的功能关系,也不利于后续的检查、迭代开发和合作。

    因此,在三四单元中,我根据分属的功能(第三单元中的Group、Network相关;第四单元的类图、状态图、时序图)对各个Java类进行归类。合理的文件组织提高了代码的可读性。

    类组织

    在类的方法设计方面,从一开始的随意将所需数据设置为类变量,到逐渐地分析各个变量的用途,有选择地将变量从类变量缩小至方法变量,到最后的严格考虑不同变量的作用范围,从而决定其生命周期的和作用域。我发现合理的变量范围的设计不仅有利于代码空间复杂度的降低,同时有利于程序员分清变量间的从属关系。

    另外,第三单元的作业给了我血的教训,彻底教会了我如何使用HashMap。虽然我已经完成了从习惯静态数组到习惯使用ArrayList的过渡,但在变量名查询这种典型的适合索引结构的程序中,我仍然使用了ArrayList+遍历这种方式进行查找,导致程序的整体时间效率大大降低。

    在类的方法设计方面,我的改变主要在于方法的长度有所下降、方法之间的耦合度下降、不同方法的功能和之间的依赖关系越加清晰等。在第一单元的作业中,我的代码在CheckStyle中反复出现超过行数限制的问题,经过了OO作业的训练,我已经能够将代码逻辑划分地较为清晰。

    在方法设计时存在的另一个问题是代码重复性过高,IDEA会对于超过6行以上的相似代码进行冗余提示,提示可以将这段代码提取成一个新的方法。但这样做存在两个问题:首先,这种相似代码段和上下文存在很多的共享数据,如果直接提取成为一个方法,会导致方法的参数过多,不易理解。另外,虽然代码相似但仍然有小范围不同时,需要对不同部分的逻辑增加选择逻辑,反而再次增加了程序的复杂性。出现这样的问题往往是前期设计时没有考虑好重复代码所在方法的功能究竟是何。

    总结自己在四个单元中测试理解与实践的演进

    作为一门软件设计的课程,测试是一门必修课。OO实验课的难点也正是测试部分,完成代码的基本功能往往相对简单,通过中测总是那么唾手可得,但互测的腥风血雨和强测的不留情面总是让我胆战心惊。经过了四个单元的学习,我学会了以下几种测试方法:

    白箱测试

    即对代码进行形式合理性的检查,以及对于手动构造的定点性已知数据的检查。在代码初始完成时,我首先会借助IDEA的报错和警示信息,查出语法层面的潜在危险。查出过后,再通过样例和手动构造的代码对于基本功能进行测试。另外,还有一种很重要的白箱测试手段,即JUnit单元测试,这是针对各个模块构造特定数据并通过断言等方式对预期值进行检查的工程方法。个人感觉JUnit和手动测试的原理无太大差异,但可以完成这一过程更加高效快速,能够迅速定位出错的位置和错误样例。

    黑箱测试

    黑箱测试是通过构造大量随机数据,将所测试程序和标准程序的输出结果进行比对的方法,这样的方法强度很高,不需要耗费过多的精力,但也存在很多问题:

    1. 黑箱测试依赖标准程序:第一单元可以通过sympy+random库的方式构造数据并得到保证准确性的数据。但之后的电梯作业、JML、UML则均没有标准程序,只能通过人工逻辑检查的方式进行,或和同学的程序进行对拍。但这样做在面对真正的工程时,实用性、可执行性有所欠缺。
    2. 边界数据难以覆盖到:第一次作业中,很多同学忽略了x^-1这样的-1开头的数据,这样的数据十分简单,但生成测试数据时,几乎不可能生成这么简单的数据。因此,边界数据的测试仍然依赖人工进行。

    综合四次作业,首先我对代码测试有了更加全面深入的理解,对于测试也更加重视,这是难得的财富。

    总结自己的课程收获

    我在OO课程中收获颇丰,前面已经提及一部分,在此进行概括性的总结:

    代码能力

    这是一个程序员的必备素养,代码能力体现在对于编程语言足够熟练的掌握、丰富的debug经验、各种数据结构和代码结构的熟练运用等等,特别地,对于Java程序而言,多线程程序设计能力是一个新的天地。我认为第一、二单元中对于Java语法本身的收获较多,而三四单元则更加侧重于对图论、数据结构的选择与优化方面进行学习。

    工程能力

    这是一个工程师的必备素养,在上学期的计算机组成课程设计中,高小鹏老师十分强调工程素养的问题。对于OO课程而言,代码逻辑功能的合理分布,文件的打包,类名、方法名、变量名的合理选取,常量宏的灵活使用,代码注释和文档,都是工程素养的体现之处。

    工程能力对于我们的迭代开发和代码维护也意义非凡,在我们的作业迭代中,代码量不断增加,逻辑功能不断扩充,这需要十分合理的架构设计才可以应对逐渐庞大代码量的统筹规划。如何进行系统的debug,发现问题之后进行修改时要保持哪些原则,这都是十分重要的。

    在理论课的学习中,我知道了各种设计模式,如“生产者-消费者模式”,“工厂模式”,“适配器模式”等等。以及各种设计原则:开闭原则、liskov原则、二八定律等等。这些理论学习相对抽象,只有在深入代码开发之后,甚至经过犯各种错误才能理解到这些设计模式和原则的重要性。

    立足于自己的体会给课程提三个具体改进建议

    1. 建议在今后的OO课程中加入合作开发的部分,形成OO小组,从而加强大家的团队协作能力,git使用技巧和完成更大工程的能力。
    2. 建议在完成作业时强制要求一定格式的代码注释,如Javadoc或JML等,方便互测同学的理解,激发互测的积极性。
    3. 建议将优秀的互测数据加入强测样例中,因为当前的强测的强度甚至不及有些互测数据。

    谈一谈线上学习oo课程的体会

    非常感谢OO课程组各位老师和助教的辛勤付出,这门课对我而言是一门十分难忘且美好的课程,我从这门课中收获了许多的知识和代码技巧,也激发了我的编程和完成较大代码工程的兴趣。希望OO课程能够越办越好!
    ------------恢复内容结束------------

  • 相关阅读:
    《时间的朋友》跨年演讲金句
    2017《时间的朋友》罗振宇跨年演讲ppt
    Calculus on Computational Graphs: Backpropagation
    Machine Learning Trick of the Day (1): Replica Trick
    What Does “Neurons that Fire Together Wire Together” Mean?
    How to Tell Science Stories with Maps
    模型选择的一些基本思想和方法
    A Gentle Guide to Machine Learning
    EM算法(Expectation Maximization Algorithm)
    混合高斯模型(Mixtures of Gaussians)和EM算法
  • 原文地址:https://www.cnblogs.com/RenJierui/p/13166624.html
Copyright © 2020-2023  润新知