Java教程

面向对象程序设计-第四单元博客

本文主要是介绍面向对象程序设计-第四单元博客,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

OO第四单元作业总结

本单元架构设计

本单元的作业架构,是基于课程组提供的需要实现的接口进行构建的。

第一次作业的架构,比较简单,但是奠定了基础。主干就是实现UmlInterfaceMyUmlIntreface,完成分析输入数据构建模型以及顶层应答查询的功能。而执行应答部分则是由各个“包装类”组成,即以官方包中的元素UmlClassUmlInterface等元素为属性而非直接继承,这样可以新添很多功能,又可以避免继承带来的难以察觉的错误。在调用这些元素的基本信息时,则可以通过多加一层简单的转发中介来实现。具体实现可参考如下:

public class MyUmlClass {
    UmlClass myClass;
    
    public MyUmlClass(/*...*/) {
        //...
    }//initialize myClass
    
    public String getId() {
        return myClass.getId();
    }
    
    //...
}

而在这些包装类中,我将如了很多新的方法和容器,用来处理图的存储分析,比如xxxNamtToId,用来在输入时保存名字到Id列表的映射关系,从而方便对重名的判断,对重名元素的寻找,等等。又如AssociatedClass,抛弃Association而直接链接到对端的类或接口,简化判断流程,增加可读性。在这些设计下,第一次作业架构大概如此。

第二次作业的架构,相较于第一次实质没有变化,仍然是以一个类为主干(只不过改名了),但是由于UML逻辑上要求三种图分开,加上官方包总接口UmlGeneralInterface其实是继承了三个逻辑上分好类的接口UmlClassModelInteractionUmlCollaborationInteractionUmlStateChartInteraction。参照这个思路,我也选择将MyUmlGeneralInterface含有为三个类MyUmlClassModelInteractionMyUmlCollaborationInteractionMyUmlStateChartInteraction的实例(此处可以采用单例模式,但我没有),然后由MyUmlGeneralInterface调用MyUmlClassModelInteractionMyUmlCollaborationInteractionMyUmlStateChartInteraction的方法来进行分析。如图

image

这样既使得结构清晰,分工明确,同时还能避免代码聚集,类代码超过500行而引发Checkstyle错误。而原来的MyUmlInterface对各个元素的管理则分别交给三者来管理。

第三次作业的架构,则只是在第二次的基础上添加了一个UmlStandardPreCheck接口用来提前检测一些Uml错误。同样,类似于第二次,我只需添加一个MyUmlStandardPreCheck类来实现它的功能即可。但是考虑到性能,我选择让第二次作业的三个新增类与它互相交流,由MyUmlStandardPreCheck来调用他们,而具体分析查询由那三个类来完成,在交流的同时也减轻耦合程度。

image

四个单元中架构设计及OO方法理解的演进

在本学期的四个单元——求导,多线程电梯,JML,UML中,架构设计的重要性始终被强调。的确,如果架构没设计好,最直观的影响就是很容易重构,在一次又一次重构中痛苦挣扎。因此好的架构是必要的。

在第一单元作业中,我进行了一次比较彻底的重构,也就是从第一次作业到第二次作业,由于突然多出了可能的嵌套和三角函数,求导瞬间变得复杂,因而不得不改变之前较大规模的正则解析,而是改成递归和小正则解析结合的方式,按照多项式的逻辑分层分别归属功能。本想着第三次作业应该不用重构了,也对可能到来的错误检查有了一定的心理准备,但是直到第三次作业真正开始分析的时候,才发现改动仍然不小,需要穿插在结构各处修修补补改改,而没有任何的预留空位,这就导致写完后我自己也不想看我自己的代码,最终还导致了互测bug(强测没错导致进错互测屋,被狠狠地捅了)。本单元最大的教训便是纸上谈兵终不如敲上三两行逼迫理解。但是怎么样让真正的理论设计分析和写代码逼迫推演理解结合,可能仍然需要考虑。

在第二单元作业中,由于第一单元作业吃亏不少,吃一堑长一智,我果断选择自己先思考一个合理的可以用三次作业的架构。查询前辈架构介绍,与他人不断讨论细节,无所不用其极。最终我选择的是分布式调度,并沿用了三次作业。但老实说,越往后仍然还是越暴露出架构设计的另一方面问题,一开始应对单、同类型多电梯还可以比较好地解决,而且简单地往上兼容不同类型的电梯迭代起来也很快,只需要改集中调度器分配原则和增加电梯的开关门判断即可,但是一旦牵扯到性能,调度就变得非常难以协调,容易顾此失彼。一方面,调度器需要尽量动态调度,但是动态调度本身就很难设计,需要有所舍弃,而选择一个可以量化的目标函数来衡量效率,和多线程搅在一起非常的麻烦;另一方面,电梯上下人需要处理多个缓存区的问题,非常的麻烦。因而这是典型的架构没能很好地适配性能要求,尽管在迭代扩展方面还是有可为的。这算是我第二单元的教训。

第三单元作业,应该是最简单的一个单元作业,按照JML规格走,小心不出错,钻研一下几个复杂的算法就差不多了。因此架构设计大概没什么可说的。但是这个单元启示我们不局限于OO的一个特点,就是形式化描述的功用。相较于伪代码,形式化语言并不那么涉及细节,而是更概括,更具指导性;相较于自然语言它又更加精确,更数学化,但是对使用者从表意方面要求也更高,一旦表意有些许差池就会引发很大的误解。因而对OO这种动不动代码量就比较大的编程方面,形式化语言算是一个很有力的工具,具有一定的概括性,又能具体到方法属性层面,但是要小心使用,符合规范。

第四单元作业其实类似于第三次作业,介绍了另一种规范语言——UML。在该单元作业中,我对架构设计其实已经有一定的经验了,能够做到拿到指导书先想一想怎么构造,减少改动,虽然有些时候还是会出现一些比较细节方面的,比如突然需要将几个属性整合出一个类单独管理,才临时想起添加。其他的不多说,上面也说过了,总之在这个单元,我对我的架构设计大概比较满意,算是付诸实现了一次自己想的架构设计的一般方法。

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

对我来说,在四个单元中,测试的重要性都不小,对于发现潜在的bug十分有效,特别是刚完成代码时完全不知道代码能够正常工作到什么程度。但是具体而言,我对测试的理解的确逐步演进了,对于如何进行测试也有了一定的心得。

在第一单元求导关,刚跨入OO大门,我完全没有写测评机,靠的是一些人为编造的有特点的算式来进行评测。缺点显而易见,覆盖面较为狭窄,综合多项特点测试比较薄弱。但是,在这个单元,我认为体现的最多的还不是自动化测试寻找bug方面的能力,而是在性能分析方面的能力。因为如果想不到某种情况的数据,那么大概率写测评机也覆盖不到,仅仅可能是能够随机碰出一些幸运数据罢了。但是自动化测试能够产生大量数据的优点,却可以弥补人造数据规模小的问题,可以通过大量数据测评比较结果(本单元是结果字符串长度),综合评分(性能分),从而帮助寻找一些拉低性能的数据特点,对症下药。(当然,很多是我从研讨课那感觉到的,因为说到底我并没有进行自动化测试)。

开始第二单元作业后,由于有了第一单元测试的诱惑,以及第二单元确实需要一定的手段来代替肉眼判断答案正确性。因此我动手写了一份自动测评机,完全由C和bat脚本完成,数据交互采用重定向利用文件进行,通过C分析输入文件来判断电梯动作是否合法,乘客是否到达目的地等。其实怎么说,自己写了才发现,自动测评机其实就是一个按照一定规律自动产生数据,然后对结果字符串进行比对的程序,只不过也需要一定的设计来尽量通用化,比如结果比对程序我一直用到第四单元乃至os,只是略加修改。本单元的自动生成数据也有一点麻烦,需要定时投喂,因此我“擅自”挪用了讨论区某位dl的定时投喂程序,利用管道来投喂。总的来说,这一单元大大增进了我对测试的认识,测试程序本身也需要一定的架构,最好是接口式的调用,定时投喂程序和字符串比较就是最好的例子。此外,利用脚本来控制操作系统辅助测试,感觉比python调库要简单。

第三单元作业,测试的压力反而没有第二次大。但是第三次完全引入了对拍的概念。第二单元其实也有对拍,但主要是对时间,但第三单元则难以得到标准答案,因而决定与他人合作,利用随机自动生成数据,将结果进行字符串比对,从而找到容易出问题的地方,再检查为何出现分歧。其他方面倒也没有很大的改变。

第四单元作业,和架构设计一样,大概也算是对测试能力的一次收官检验。然而我在第四单元错的也不少,尽管也进行了测试,但是测试力度明显不如前几次,可能是因为临近烤漆,没有太大的动力,而且数据相对更难造出。但是如果真的要做测试,本单元应该对拍和时间相结合,自动测试与手动构造相结合,因为既有对UML的理解不知是否正确的疑惑,又有图计算对复杂度的压力,因而相对覆盖较为全面。

总结自己的课程收获

经过一个学期的OO课程的锻炼(雾),我觉得OO对于设计这一门博大精深的艺术还是没有完全弄明白,只是开了一个头,毕竟靠精湛的设计建模吃饭的人不在多数,绝不可能这么简单。反复的局部重构,错综复杂的交错关系,让人纠结不已的加接口加类,都是没有提前设计的真实后效,也是我常常遇到的问题。不该还好,现在我还是通过OO意识到了这个问题,提前设计这一提醒是OO课给我带来的一大收获,写代码绝不是直接莽就可以了。

此外,我也学到一些Java的知识,虽然不算很多。其中之一就是多线程的使用,算是完整学到的一个大块的知识点了,也结合了操作系统学到的知识,对计算机的工作原理进行了了解。

还有一点可能不完全相关的感想,那就是由OO而对一些前后端工程设计也有了一点兴趣。无论是OO评测网站的搭建,还是后端测评机的运行,抑或是gitlab的协调使用,大概让我感受到什么是一项系统工程,怎样将可能用到的东西都用技术化归下来,这一点算是让我对黑框框以外的编程设计有了兴趣,但将会是什么可能还需要我进一步去发现。

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

1.希望课程组能够参考一下大部分同学们的课表,不要让主要写oo的时间与太多同学的课程时间重叠,导致时间比较紧张。

2.希望测评形式更加开放,在功能上满足要求,实现方式更多样化,毕竟同学们总是与课程组争论某些细节上的正确性比较麻烦(当然只是建议,毕竟这样测评将会变得不方便精确赋分,具体形式完全还需要商讨)

3.研讨课可以与实验课结合更紧密,而不是作为同一时间交替的互不相干的课程,比如研讨课也可以介绍实验课的相关细节,特别是实验课是拓展环节时。

4.虽然知道OO不是Java课,但是许多Java相关的知识还是非常有必要的,感觉还是让同学们在大二多学一点知识比较好

这篇关于面向对象程序设计-第四单元博客的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!