OO第四单元总结

OO第四单元总结

第四单元架构设计

hw13

在hw13中,我们需要实现一个类图解析器,我们要完成MyImplementation类以实现对于读入UML语言的解析。我们需要解析的元素类型自上而下有:

1.Class、Interface、AssociationEnd

2.Operation、Attribute、Association、Generalization、InterfaceRealization

3.Parameter

我们按照以上的层次分三次读入元素,可以实现一步步的解析。例如,我们先读入所有的Class元素,然后再读入Operation元素,这样就可以把Operation的信息存入对应的Class类元素中,同理Paramter对于Operation也是如此。

为了实现解析的目的并提供查询的功能,我们需要对基础的模型进行封装,以便我们能加入便于查询的内容。从实际上看,例如Parameter、Attribute这样的元素并没有封装的需求,但是既然其他的类都封装了,如果这些类不进行封装,那么我们在具体写代码的时候容易分不清改用什么类的情况,因此我们把所有的Uml元素都进行封装。例如,将UmlClass类封装为MyClass类,在其中加入opMap用于存储对应的operation,attriMap用于存储对应的attribute,superClass用于存储其继承的父类等等。

在完成解析、封装后,我们就可以着手添加查询功能了。MyImplementation从UserApi接口继承来了对应的查询方法。在这些方法中,常常需要根据类或者方法的name属性进行查询,而我们在存储的过程中,根据元素id为非重复的这一特点选择以id为key来存储各种元素,这就引起了查询时的不便,所以我们在解析的过程中需要创建并维护一个用于将name与id进行转换的Hashmap。例如:

HashMap<String, ArrayList<String>> classNameToClassId

key就是类的name属性,而ArrayList中存储的元素是此name对应的id,我们可以根据它的大小是否为1判断类是否重名,可以看到,此HashMap的建立还便于我们抛出异常了。

个人觉得最难实现的是5,下面简单谈谈我的实现方法:

1.操作5需要判断parameter是否有类型错误,在创建MyParameter对象的时候,我就判断了是否有类型错误,然后在MyOperation类中提供hasWrongTypeParam方法,用于判断它下属的parameter是否有类型错误。

2.关于重复操作的判断,我使用的是for循环嵌套,先判断两个同名操作的参数数量是否相同,如果相同在比较同类型的参数数量是否相同,如果每一个类型的参数数量都相同,那么二者就是重复操作。

3.最后判断CouplingDegree不是很难,只要用set存储参数类型,最后判断一下是否包含类本身的这个类型的参数,有的话返回set大小减一就行,没有就返回set大小。

hw14

本次中要添加顺序图和状态转移图的元素,因此我又创建了两个package,分别存放二者对应的新加类。与类图相似的,我们需要按照层次划分状态转移图与顺序图,并且依次读入与解析。

顺序图:

1.MyCollaboration

2.MyInteraction、MyAttribute

3.MyLifeLine、MyEndPoint

4.MyMessage

状态转移图

1.MyRegion

2.MyStateMachine

3.MyState、MyFinalState、MyPseudoState

4.MyTransition

5.MyEvent、MyOpaqueBehavior

本次添加的查询操作大体上不难,用和hw13类似的方法基本可以解决。

唯一需复杂一些的操作就是判断是否为关键节点的getStateIsCriticalPoint方法。

下面简单讲讲思路,我们使用dfs遍历,从起始状态开始,遍历完成后,去查对应的visitedMap,如果任意一个finalState显示被访问过,那么表示可以到达finalState,接下来从图中删去这个节点,再次使用dfs遍历,如果此时无法到finalState状态,那么就说明这个节点是关键节点。

hw15

没什么大改,除了一个hw14遗留下来的问题(当时认为collaboration只有一个,debug的时候发现可以有多个,遂改成用HashMap存了,并改了解析interaction时分配到collaboration的过程)

最难的就是循环继承的判断了,别的不是很难。循环继承本质就是找圈,我了解到的有效率非常不错的算法,如Johnson算法等,根据强连通图来找圈,然而我不太会,就用了个有点蠢的方法,就是用递归法找到所有extends的对象,然后查二者之间有没有有向边,如果能找到指向自己的边,那么说明此节点一定在圈中,只要遍历所有节点,就能得到所有在圈中的集合。效率非常差,但是测评不看效率:)。所以我毅然决然使用了这个呆逼方法,因为难的没用过,可能写错,而且没有对应代码让我copy一下。

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

第一单元

第一单元的开始真的没什么头绪,看着实验课的代码懵逼,后来开始慢慢理解了递归下降的方法,慢慢学正则式。起初是没什么面向对象的概念的,喜欢把所有东西都写在一起,但是递归下降这个模型本身就是个很oo的例子,在这里想使用面向过程也是比较困难的,我对着学长的代码,心里对于面向对象慢慢有了一个概念,对象就是把属性和方法封装起来,作为一个整体来创建与调用。在解析表达式的时候,脑子里也有了把表达式拆分的思想,把复杂的式子拆成单项式、常数、三角函数等等,通过管理不同类型的对象,实现解析表达式。

由于刚接触oo,设计思想还不是很成熟,但是慢慢已经开始有了概念。

第二单元

第二单元开始接触多线程编程,说实话我在第一单元就吃了闭门羹,对于传说中最难的电梯,内心还是有点恐惧的,但是又急于想证明自己不是完全做不来oo作业,就开始认真学习多线程知识。这一过程中学习了生产者消费者方法,这个经典的设计方法,对于oo思想就是一个很好的诠释,将整个流程分为生产者、消费者、容器,各司其职,非常面向对象。

通过对于电梯的设计,我对于oo的理解大大加深,和同学们也进行了很多讨论,在一次次的重构和优化中,我知道了如何做一个更好的、更简洁且耦合度更低的设计,抽象建模能力得到了提升。多线程单元是我自认为提升最大的一个单元,我没有去纠结如何优化性能,我认为那是算法的问题,跟oo没多大关系,而理解好架构才是我这种菜鸟优先应该思考的问题。

第三单元

第三单元的契约式编程,通过jml的学习,了解到了这种新的描述方法,可以说是介于整体的架构和具体的代码之间的一个规范,一种精确但略显繁琐的约束。它很像我们在离散数学中学到的数理逻辑,严谨但不说人话。我认为它的作用就是让我们有一个检查具体设计正确性的依据,它需求抽象后的产物,指导了我们怎么具体实现代码,算是debug时有利的帮手,要是哪天能搞出个自动写jml的东西,那以后的coding就成了纯体力活了,再后来估计coding都不用人干了,直接自动补齐(×)。

这单元oo吗,我不是很好说,但是它确实向我们介绍了架构设计中的一个中间环节,让我们了解到了一些新知识,顺便复习复习数据结构(×)

第四单元

第四单元的UML,我觉得非常配得上面向对象,因为我们解析的真的就是一个个对象(UML图中的元素)我们要把输入的一整个UML图拆分成不同的对象,并且根据他们间的关联,进行解析,并提供查询方法。这一单元中,我们学到的知识,对于设计架构而言非常有用,UML图是每一个程序员都应该学会画的,我们看到需求,首先就应该想到的时建模,然后才是coding,可以说在建模面前,coding的重要性要低的多。不光是类与类之间的继承等关系,还有类与类间的协作,整个架构状态间的转移,这都是非常oo的内容,也是我们在动手之前应该想清楚的事情,而UML图提供了class diagram、sequenced diagram、state diagram,分别对应了以上三种图的建模,可以说它是oo思想的集大成,oo的精髓就在一张张的设计图中,Java还有那个C++嗷,都往后稍一稍。

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

完全随机

采用完全随机的策略,通过扩大测试次数以及单次测试的指令规模发现Bug

单元随机

可动态调整各指令出现的概率和指令中id生成的概率等,集中测试相应的功能模块

总结自己的课程收获

java编程能力

在短短一星期之内速成java基础知识,对java的核心类和编程语法有了较为全面的理解,培养了我的编程能力。

从面对过程程序设计到面向对象程序设计的思想转变

第一单元的学习,让我深刻明白了什么是面向对象,什么是类,我们该在什么时候创建一个类,该如何去实用类。

多线程编程的设计思想

第二单元的学习,让我对多线程的学习有了较为深刻的了解,我们该如何去保证各个线程之间的安全性,怎么运用锁。

JML/UML规范化源码的阅读理解能力

第三单元的学习,让我对JML语言有了较为全面的理解。

架构设计能力

四次作业都有一个核心,就是架构设计,架构设计应该在大规模细节化编程之前,这样不但可以使得我们的思路更加清晰,编程效率提升,并且也对往后的迭代有促进作用,减少remake的可能性。

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

1.第一单元表达式的难度问题

第一单元上来第一次作业的难度就是相当大的,而且熟悉指导书也需要一个过程,我觉得只给一个星期不到的时间太过于严苛,建议开始前先以第一次作业为例,讲一讲oo作业的设计思路等等,为同学们提供一个良好的方法论,上来就把难度拔得那么高显然不是个合适的教学方法,因为你这课一开始本来就什么都没有教,我觉得这样弄是不合理的,就算你不讲,也可以适当延长提交时间。第二单元赶上了假期,可以提供更充足的时间让同学了解多线程的知识,为自己的设计提供思路,但是第一单元并没有。这样就很容易导致大家无从下手,从而积难成疾,最后丧失信心。不要怪大家不主动问,有的时候确实是和同学讨论了,但是还是没能好好理解,希望老师和助教可以多多关注第一次遇到问题的同学,有的同学可能比较内向不太好意思问,如果助教和老师能及时提供帮助,可能会让课程显得更有温度。(总体上来将oo是个有温度的课程,比如说假期和期末ddl延期的操作,还是让我等学渣觉得很暖心的。)

2.提供补交机制

我觉得课程本身是希望大家能够学会oo的设计思想,并且会写一手流利的Java,而不是靠ddl卡同学们,让大家得不到相应的分数。有的时候可能就差一点点就完成了,或者因为有些事情耽搁了,我觉得课程组应该提供这种对应的措施,让大家不会因为这个事情精神紧张一整个星期,我觉得这样会让大家更喜欢这个课程。当然,补交也是要有一定限制的,不然很容易被钻空子,我觉得可以设置补交次数限制,最多补交3次或是几次,然后强测分数随着补交时间的早晚相应地扣除一部分,这样是不是更加合理一点呢(虽然可能会增大助教评测的压力,但是我觉得对于提高课程体验感非常重要,毕竟第一二单元那会真是写的相当痛苦,如果能够有一两天额外的时间,我觉得内心感受真的会好太多)。

3.评测教学

我觉得官方可以提供一下每个单元的评测思路,让测试基础薄弱的同学有信心去做自主的评测,甚至撰写评测机,我觉得这对于培养大家的测试能力是有很大意义的,毕竟不是每个人都有那种能力去靠自己收集资源做评测工作,尤其是不抱团取暖的单干户,如果课程组能提供详实的教程,可以大大提升学习效率,也能更好地满足课程组的要求,同时能提升自己的能力。

posted @ 2022-06-29 13:33  KKbecomesbald  阅读(33)  评论(1编辑  收藏  举报