BUAA OO 第四单元总结&课程总结

BUAA OO 第四单元总结&课程总结

🖊概述

​ 本单元的目标是在课程组提供的UML解析程序基础之上,封装自己的UML元素类来建模、指令查询和抛出异常等。在此之前需要熟悉UML类图、顺序图和状态图各个元素之间的基本关系,以便建立恰当的模型。

🗺架构设计

​ 三次作业是增量开发的关系,每次作业在之前的基础上添加新的功能(新的查询指令或者抛出异常),总体难度较低,但是工作量不小,需要兼顾到整体设计架构的简洁性和实现功能的正确性。

​ 其中有三个类(ClassDiagramSequenceDiagramStateDiagram)是工具类,包含一些静态方法供UserApiImpl调用,否则会超行数😀。另外为了建模方便,构造方法中给出的UmlElement的顺序不一定满足需要,因为有些元素需要提前处理,所以在开始的时候我进行了排序,部分代码片段如下。(选择.stream().sorted()的原因是UmlMessage在列表中是按顺序排好的,需要保证排序的稳定性,因此不能使用普通的.sort()

    private int elementWeight(UmlElement e) {
        return (e instanceof UmlClass ||
                e instanceof UmlStateMachine ||
                e instanceof UmlCollaboration) ? 0 :
                (e instanceof UmlInterface ||
                    e instanceof UmlRegion ||
                        e instanceof UmlInteraction) ? 1 :
                        (e instanceof UmlOperation ||
                            e instanceof UmlPseudostate ||
                                e instanceof UmlState ||
                                e instanceof UmlFinalState ||
                                e instanceof UmlLifeline ||
                                e instanceof UmlEndpoint) ? 2 :
                                (e instanceof UmlTransition) ? 3 :
                                        (e instanceof UmlParameter ||
                                                e instanceof UmlEvent ||
                                                e instanceof UmlMessage ||
                                                e instanceof UmlAssociation) ? 4 : 5;
    }

    public UserApiImpl(UmlElement... elements) {
        ArrayList<UmlElement> elementList = new ArrayList<>(Arrays.asList(elements));
        elementList = (ArrayList<UmlElement>) elementList.stream()
                .sorted(Comparator.comparing(this::elementWeight))
                .collect(Collectors.toList());
        // HANDLE UMLELEMENTS
    }

🏃‍♀️设计思维和OO理解演进

第一单元

​ 经过了假期的Pre训练,我对Java语法和面向对象有了初步的认识,但还是被第一单元难住了。(x

​ 第一单元中最重要的一步是抽象表达式元素的结构和相互之间的关系,比如三角函数如何存储、如何找到表达式计算的好方法等等问题都是必须考虑的。第一次作业因为没有引入其他函数和变量,因此一个HashMap<Integer, Integer>完全可以胜任,但是在后续的作业中就不得不重构了,遗憾的是我当时没有在找到一个合适的结构,导致三次作业中完全没有继承关系 + 一些类中的方法很臃肿,有的方法甚至套了七八层大括号(幸好只有三次作业😀)。

​ 幸运的是在第一单元中我深刻认识到面向对象编程思想和设计模式的重要性,在之后的作业中加以注意,没有犯类似的错误。

第二单元

​ 第二单元中我第一次接触到Java多线程的相关知识,在入门的时候花了很多时间来学习和构思。最终大概思路是构建一个或若干个线程安全类,其实例作为线程之间的“桥梁”,每个线程之间的逻辑是相对独立的。细节方面主要是注意锁的使用和synchronized块的范围(我就因此在第一次作业中出现了bug),以及消除轮询。因为第一次作业建立了一个还算合理的架构和电梯调度的算法(后面就没有动过,LOL),所以后面两次作业就比较顺利,线程之间如何沟通、同步等等都比较熟练,代码的逻辑性和条理性也得到了提升。

第三单元

​ 第三单元学习了JML语言体系并且初步接触了契约式编程,主要是根据给定的规格来构造社交网络并实现特定的功能。简单来说就是给定一个框架,包括条件、结果和影响等等,如何实现还是见仁见智。在第三单元中我学习了契约式编程的实现和相关细节,并且复习了一些图论算法,整体工作量上比前两个单元要少很多。

第四单元

​ 第四单元主要是建立UML的模型并实现查询和抛出异常等功能。总体难度不大,重点是要熟悉UML类图、顺序图和状态图各个元素之间的关系。需要注意的是要仔细阅读指导书,完全理解功能的含义再着手写代码,否则很可能会出现bug。

✔测试实践的演进

第一单元

​ 第一单元的测试主要基于手动构造样例的形式展开,给出若干个比较长的数据点并和结果进行比较。其中比较的过程我借助了Mathematica的工具来验证,比如统一代入1比较结果即可。由于两个不恒等的表达式代入之后误差小于阈值的可能性极小,因此这种验证方法还算可靠。当然也可以使用python的相关库来实现。

第二单元

​ 第二单元的测试也是基于手动构造样例的形式,可以构造很极端的数据(比如第69.9秒的时候突然增加若干请求来测试高并发情况下的正确性)。在线程轮询的排除方面我使用了jcommander来跟踪程序运行的各种状态。除此之外我还使用了室友写的小程序,它可以将无序且杂乱的输出按照电梯的序号来一一整理,这样就能直接查看具体某一部电梯的运行状态,非常方便。

第三单元

​ 第三单元个人感觉把指导书上每个细节都注意到就基本上不会有太大问题,主要还是性能方面可能会造成bug。在写算法的时候要注意复杂度和函数调用栈等等,总之要时刻注意可能出现的超时问题,因为互测大家都是用极端数据炸人。测试方面我只写了一个测试极端数据的数据生成器,主要还是靠和室友对拍来验证。

第四单元

​ 第四单元和第三单元类似,搞清楚指导书并把讨论区的问题过一遍可以帮助排除一些bug,当然最好还是从头到尾把自己写的程序逻辑过一遍(可以自己给自己讲讲实现的思路,也许会找到bug也说不定)。第三次作业的压缩包里给出了每个异常对应的UML图,把这些都验证一遍就可以排除很多bug。

🙌课程收获

​ 这一学期的课程下来,最直接的收获当然是体会了解并内化了面向对象的思想和一些设计模式,逐渐抛弃了一些面向过程编程的小毛病,写出来的代码更优雅、可读性更强了(checkstyle插件功不可没,逃)。

​ 除此之外一个让我明显感觉到的收获是:不怕写代码了。如果说上学期的计组还是我对码代码脱敏的预备期,那么这学期经过OO和OS的双重考验,我想我对写代码这件事已经没有了大一时候隐隐的恐惧。每次作业动辄上千行代码和重构的经历使我在思考代码本身的同时必须兼顾到整个架构的合理性和复杂度,这些都是写代码必备的能力,会很多算法和编程技巧是一方面,拥有架构设计和组织的能力并应用到实际编程当中也是很重要的。

💫一些小建议

  1. 多线程的相关知识可以提前下放,比如在预习任务里稍微涉及一点点,或者干脆让第二单元多一次作业并砍掉第三或者第四单元的一次作业。本学期第二单元第一次作业因为假期而延长了几天时间,这几天时间刚刚好让我熟悉了多线程的知识并理清楚了思路,不知道是不是每学期第二单元都恰巧能赶上一次假期🤔。
  2. 关于研讨课,个人认为安排不够合理:一方面留给小组讨论和展示的时间比较仓促;一方面在某些讨论题下大家得出的结论可能是比较相似的,上台展示内容的重合度也比较高,这样一来大家的收获相比花掉的时间来说会相对减少。可以适当延长一些讨论的时间并减少上台展示的人数,比如可以等讨论结束抽签一些组来展示,这样大家都有足够的机会参与到讨论当中,也给展示环节减少了负担(个人经验是几乎没有哪次可以所有组都讲完的)。然后课下可以所有人维护一个讨论课总结文档,每一组把讨论的结果写进去,这样也给没有展示的小组补充观点的机会,deadline过了之后再整合一下文档发给同学阅读。这学期的研讨课感觉课上大家整体参与度不是太高,课下总结文档提交完问卷星就石沉大海,这两方面都可以提高一些效率。
  3. 互测阶段可以开放star的功能。如果看到同房间有同学的代码写得比较优雅,可以star标记一下,在本单元结束之后公布一下这些同学的代码供同学们学习。然后同房间被star最多的同学可以在互测或者强测环节酌情加分(或者扣分减免)🤔?也许互测可以增加“star一位同学的代码”的要求,并且需要下载所有代码之后才可以star,这样也符合互测的目的,哪怕不肉眼debug其他同学的代码,看看其他实现方法也是好的(感觉大多数同学到后面就是直接造数据hack一个算一个)。只是一个初步的想法,为了保证平衡性可能还有很多细节要实现。
posted @ 2022-06-23 23:05  alxzzz  阅读(62)  评论(0编辑  收藏  举报