BUAA-OO-第四单元(Uml简单解析器)暨课程总结
BUAA-OO-第四单元(Uml简单解析器)暨课程总结
一、 作业设计架构
这三次作业的基本设计原则是建立与Uml的各种module一一对应的类(如果确实不需要也可以不建立相应得类)。
第一次作业
其中的Myxxx类都是与Uml的module相对应的,而UMLattribute由于较为简单,因此没有开辟新的类进行存储。
第二次作业
第二次作业在第一次作业的基础上扩展了对UmlCollaboration、UmlStateMachine的支持。
第三次作业
在这次作业中,新增加的ValidationCheck大部分直接嵌入了相对应的类中,而对类的检查由于较为复杂单独抽象出一个类,对Class的部分属性进行检查。
架构的优化方向
在做完这三次作业后,如果需要要优化自己的程序结构,应当有如下的优化方向:
- 提取
Class
和Interface
共性的部分,使它们共同继承MyClassifier
接口,从而在ClassModuleInteraction
中遵循依赖倒置的原则提高代码的复用程度。 Myxxx
直接继承官方实现的Umlxxx
,构造时进行拷贝构造,使得在存储和查询时无需维护和查找对应的HashMap,提高代码的可读性。- 为各个递归的检查算法实现更好的代码复用(如使用泛型容器和参数,对不同的需要递归查询的对象复用代码)。
二、架构设计演进与OO思想的演进
第一单元(表达式求导)
无脑大数组-->认为所谓OO就是那棵表达式树-->被正确性检查和化简折磨的快哭了没时间想啥是OO
虽然三次作业让自己欲哭无泪甚至产生退课的想法,但最后还是在总结课中有一点OO的思想即无论三角函数还是幂函数,无论是他们相加还是相乘,都可以看做(在代码中实现为)一个derivableObject
,不同的类型在derive
、print
时调用自己的相应的方法。虽然在第二次作业中由于为了追求化简而强测结果惨淡,但从学习知识的角度而言,发现自己能够地实现一个以前自己从没敢想过的支持复杂数学表达式的求导程序还是不错的。
第二单元(多线程电梯调度)
艰难理解多线程原理-->用OO的思想集中管理会并发访存的容器-->在第二三次作业中轻松迭代开发
当然这个单元最大的难点在于多线程编程。在很好地理解多线程的原理后,就会发现synchronized
关键字就很好地为我们屏蔽了同步互斥的底层实现。三次作业的实现难度也会在掌握的同步互斥的原理后受到降维打击(cj不追求性能)。最基础的OO思想当然是一一对应需要实现的类(Elvator、Request、InputThread),此后,笔者便会开始考虑各个类管理的边界。如Elvator到底要不要知道外部所有楼层乘客的请求?是否有必要实现Dispatcher?Dispatcher是否需要知道各个电梯的工作状态?这些问题当然没有绝对正确的答案。但确定各个类的边界确实是OO编程中需要反复考量的一件事。此外,第三次作业实现换乘,使得笔者不得不将官方的Request进行拷贝构造为新的Request。在发现这样做的优势后,也开始对类与类之间的耦合问题有所思考(显然如果更进一步提高需求的复杂程度这样做是让程序更加符合开闭原则的)。
在这个单元中也初步接触了SOLID原则,在此后的实践中也发现这些原则确实很有道理,值得遵循这些原则写出更加OO的代码。
第三单元(完成交互网络的接口)
了解JML语法-->根据接口说明实现各个方法-->并查集、Tarjan算法的学习与实践
这个单元OO的思想即:先想好每个类有哪些接口,接口要实现的功能和传进传出的条件、抛异常的可能等等。完成这些设计后,在完成每个接口时,只要能够满足约定的条件,想怎么实现都行(当然这个单元要求我们控制时间复杂度地实现)。当然,由于必须个人独立完成作业,所以并没有实践感受到这样做的好处。相信未来如果自己成为一名架构设计师(~糊),在设计出类似的框架让别人去实现,或者自己按照要求实现具体接口时,才会体验到这样做的好处吧。
第四单元(简单的Uml解析器)
了解Uml并在StarUml中实践领悟-->没了
这个单元需要我们解析的UmlModule本身就相当OO,所以再让我们钻研如何对其进行解析就算双倍的OO了吧?
当然架构也很重要,自己的架构当然大体上直接与模型所需相同,但细节实现并不是很好(比如发现建立了一堆用于查询的HashMap,许多递归检查本身具有高度的相似性却没有很好地实现代码复用等等)。
三、测试的理解与演进
之前对于测试一直都不是很了解,也是在OO课程逐渐建立起对测试的简单认知:
- 黑盒测试:将程序整体打包,有外部的测试人员构造测试数据进行测试。这种测试也可以分为两种:手工构造和随机生成,当然,这样的数据点要想具有一定的强度,就需要对指导书和一般程序的边界容易犯问题有很好的了解。
- 单元测试:(在Java中通过Junit呈现),需要对程序的各个接口比较了解的人(或者程序代码本身对每个接口给出了较为详细的形式化或者自然语言形式的描述)构造对每个模块单独的测试数据。这样做相对直接将整个程序直接进行测试,优点在于细化了测试的单位,使得出错时能更快的定位bug,且具有良好的复用性。
- 程序自带"测试"(更多的是一种反馈):JML单元汇总,给出部分的前置条件为
xxx!=null
orxxx < xxx
,对于这样的前置条件,我们可以在接口一开始就通过assert
断言在发现问题后即使终止程序。或者抛出异常压入自己构造的异常栈中,这样能很方便的在未来的测试中定位bug。 Formal Varification
: under construction...
此外,感觉像IDEA这样较为高级的IDE中的代码覆盖率的功能相当不错,而事实上,计算机程序的特点就在于重复执行,因而错误往往会发生在第一次执行,因此,如果测试能够做到百分百覆盖,应当可以称之为一次相当不错的测试了。
四、课程收获
虽然被整的很惨,但是OO确实是我学到的东西最多的课。
OO思想从0到1的建立、较大工程(相对C语言课程50行的代码而言)的开发,各种数据结构和算法的实战现学现用、测评机的设计、IDEA的使用...其实广义地说,这四篇总结总结的都是笔者的收获,所以就不再多说了~
那么请让类似OO这样的暴风雨般的课来的更多一点吧
五、改进建议
第一条
- 主要提一个现象吧(来自一个cj的视角):在这个课程的各次作业中,会有许多大佬抱团在一起,合作构造数据生成器、在数据较难检验时进行对拍。这些同学往往能很快地定位bug,并在互测环节直接将同屋的同学的程序导入其中,也会很快hack出别人的bug。因而这些抱团取暖的同学往往具有不错的学习体验和成绩。而与之相对的(比如我),虽然第四次作业虽然
被咬了才知道疼痛定思痛决定抱巨佬大腿,但已经没有了公测这一环节。在前三次作业中并没有寻找同学构造数据和对拍,没有能够及时发现自己的错误。因而在第一单元的第二次作业和第三单元的第二次作业中大崩盘,没有进入互测,也没有机会体验一边学习同学的代码,一边寻找其中的bug;在第二单元,也由于自己没有很好的测评装置,对于同组互测的同学的程序,或者无法找到bug,或者由于无法在本机创造较大的压力条件在本地发现了别人程序死锁或者错误,却无法复现。可以说学习的体验感不是很好(当然成绩也不好就认自己cai吧)。我想,像我一样因为无法(或者说没去尝试)和同学组成帮助小组而失去了很多学习体验的同学应该也有一些。我们这些本来就不是很厉害的同学也很渴望更好地参与BUAA's CS's OO's legendary Archtecture
中去的呀! - 关于这个现象的改进意见:说实话,这其实是笔者这样的不是很厉害的同学自己的问题(就不明确指出是哪方面的问题了)。但我觉得课程组可以做一点点事稍稍推推我们这样的同学:
- 在第一次课上鼓励同学们结成互助小组
- 由OO助教出面,对可能有好几次作业强测成绩不理想的同学好言相劝,告诉这些同学:咳咳, "有许多同学强测成绩很好并不是因为真的很厉害(善意的谎言~),而是组成了互助小组...我帮你找了几个和你情况相似,也希望找到其他同学一起报团取暖的,你希不希望认识一下...“
似乎需要写三条emm...
第二条
笔者看助教去年的博客比较好的建议比如课上测试给答案啥的在这一届似乎也没实现...(小声),所以希望助教和老师能看一看笔者的
第一条建议。
第三条
笔者看助教去年的博客很多比较好的实现难度不大的建议比如课上测试给答案啥的在这一届似乎也没实现...(超小声),所以所以希望助教和老师能看一看笔者的第一条建议。
EndNote
OO(Object_Oriented)究竟是什么,具体的说,可以说是类、是继承、是多态、是...;抽象地说,它她是Everthing is Object
,是SOLID原则,是我们的课程中上课所讲的那些大道理。然而我们都是具有辩证唯物思想的马克思主义的追随者,那么我们对于OO的透彻理解可能就需要从具体到抽象,再到升华的具体。借此,笔者也希望以Bruce Eckel在Thinking in C++中的一段话结束自己悲惨的OO课程:
OO(Classes) designed to fit the problem tend to express it better. This means that when you write the code, you’re describing your solution in the terms of the problem space rather than the terms of the computer, which is the solution space . It helps you deal with higher-level concepts and can do much more with a single line of code.
bang!
Terrorists win!