一、架构设计:
本次作业需要对UML类图,顺序图,状态图进行建模,其基本的层次,即:父子关系如下:
类图 | 时序图 | 状态图 | |
---|---|---|---|
1 | UmlClass、UmlInterface、UmlAssociationEnd | UmlInteraction | UmlStateMachine |
2 | UmlOperation、UmlAttribute、UmlGeneralization、UmlInterfaceRealization、UmlAssociation | UmlLifeline、UmlEndpoint | UmlRegion |
3 | UmlParameter | UmlMessage | UmlPseudostate、UmlState、UmlFinalState |
4 | UmlTransition | ||
5 | UmlEvent |
在初始化时可以按照上面的层次关系重新将输入的元素分类,再从前往后遍历各个遍历,只有从前往后遍历才能保证后面层次对前面的依赖关系。在初始化时,将UML中的id转换为具体的元素存并用HashMap进行存储,从而使得查询更加简便快捷。
-
第一次作业:
由于此时对于UML图并不是特别熟练,并且是一个从无到有的建模过程,面对官方包中的UML类时,它们并不能完全满足需要,所以我将所有要用到的UML类对应的建立了自己的类,即:MyXXX。
在自己的类中可以直接将各种parent关系,继承关系,关联关系等由id转换成具体的对象,从而提高了查询的速度,能够更加便捷的访问。用HashMap存储可以将id和对象进行一一对应。
在初始化时遵从以下规则:
1.将类保存进HashMap
2.若有parent则通过id检索HashMap找出其parent并将其存入到parent中,同时设置其parent
指令实现:
指令2:需要求出类的所有子类,由于可能出现跨代的继承,可通过递归算法不断的求其子类的子类,直到子类为空,将这些所有的子类装入到集合中并返回该集合即可实现查询子类。同时可将该集合直接存入到初始类的对象中,如果重复查询同一个类,只需要返回该集合即可,无须再次递归。
指令7:找出全部的实现接口,同样采取递归的方式,边递归边记录实现的接口,直到father为空。
指令5,6:计算耦合度,其难点不在于耦合度的计算,而在于诸多异常条件的判断。对于重名异常的判断,可在建模时就确定,即若HashMap中已存在的一个同名元素要加入时,将其加入到repeatname容器中,在查询时若name处在repeatname容器,则抛出异常。
-
第二次作业:
有了第一次代码的架构,只需要将状态图和顺序的图的架构加入到原代码中即可。
同样对于新的UML类建立自己的新类MyXXX,在类中同样记录各种关系,加入新的方法。
对于此次作业相对较难的是寻找“关键节点”,主要方法也是使用DFS算法,从初始状态开始将要查询的结点作为参数传入每一次递归,如遇到该结点则跳过对该结点的递归,在递归中再判断是否到达了最终状态。
-
第三次作业:
第三次作业主要针对于UML图不符合规范的情况。
其主要难点在于对R002的理解:即“成员属性(UMLAttribute)和关联的另一端所连接的 UMLAssociationEnd 这两者构成的整体”如何理解
此外:R003,R004也需要用到一些递归的思想
R003:对所有的点不断取其father进行递归,若出现了father为起点的情况则已经成环,将其记录下来即可。
R004:同样不断向上递推,记录已经继承的类,若发现重复,则记录下来。此处需要注意,同一个类也可能重复继承一个类两次,此处由于HashMap的equal方法不会重复添加,此处应该在初始化建模时就将有重复的类用另一个容器记录下来,在之后直接查询即可。
二、架构设计思维及OO方法理解的演进:
OO是一门理论与实践并重的课程,脱离于理论,实践起来将寸步难行,不进行实践,理论也只是纸上谈兵
第一单元
虽然在寒假中也有认真的完成了pre但其实只是熟悉了java语言的使用,第一次作业还是无从下手,由于没有面向对象的概念,直接按照面向过程的方式了写,导致了诸多问题已经频繁的重构。之后经过课上实验,了解了一些代码的架构才逐步理解了面向对象的原理。慢慢理解了OO设计的精妙就在于把每一种数据和其对应的方法设计成一个类,构成面向对象的模式,同时不同类之间还有层次结构。第一单元由于概念的缺乏,没有理论指导的实践,做了许多无用功。现在看来,即使是经过了多次重构,第一单元的层次化设计依然不够理想,并没有清晰的为各级表达式确定层次关系,仍旧存在许多面向过程的影子。
第二单元
第二单元主要设及多线程的理解和运用,多线程需要理解并发和互斥的关系,而其具体的实现方式则是加锁。这些思想在os的课程中也有所涉及。由于有了第一单元的基础,对于层次化设计逐渐熟悉,基本上对各个电梯单独的设计已经较为轻松。对于任务的分配采用了一个调度器线程来分配然后使用生产者-消费者模型来连接调度器和电梯。另外一个难点是电梯的调度算法,电梯调度没有最优解,而look算法是一种相对实现简单而高效的方法。
第三单元
第三单元主要是理解jml语言,需要写的代码并不多。通过这一单元的学习主要熟悉了jml语言的使用。同时,这一单元也略微涉及了算法的性能问题。同时也学会了使用并查集来实现图的结构并查询图的特性。
第四单元
第四单元主要是对于UML图的理解和分析。在完成作业的同时进一步加深了对UML图的理解,并了解了UML图中的各种关系,如:继承,关联,实现。同时了解了UML类图,顺序图,状态图的基本概念以及三者之间的联系。在具体的算法和建模方面并没有遇到多大的困难。
oo为我们提供了一种全新的编程思想,不再是将一个过程分为若干个阶段来建立函数,而是将每个类设置为一个属性与方法的集合,通过调用这些方法来完成目标。这种方法更适合复杂度较高的项目,可以是编程更加有条理,由宏观到微观再到宏观地逐步地层次化的实现功能。
三、四个单元测试的实践与理解:
第一单元:由于对于oo的不熟悉,仅仅是完成代码就花费了大量的时间,并没有在测试上下太多功夫,主要还是手工构造了一些边界数据进行测试,同时还借用了其他同学的一些测试数据。
第二单元:测试主要也是集中在了边界测试上,通过测试测出了超载的一些bug,同时也与其他同学的代码进行了一些对拍。
第三单元:学习了一下Junit的测试方法,可以辅助编写一些测试程序来对每一个方法进行测试,但对于测试数据的构造起始帮助有限。
第四单元:此单元相对简单,主要测试了一些递归的函数,防止无限递归即可。
四、课程收获:
- 学习到了面向对象的设计思想,从第一单元用面向过程方法走入绝境到逐步使用新的思想绝处逢生。
- 增强了设计的意识,写代码时不应直接拿到题目就写,而应先思考设计框架结构,这样可以减少出错和重构的次数,也能够使得体系更加容易迭代。若前期设计不合理反而会浪费更多时间。
- 设计时应考虑到程序的可扩展性。对于每个单元的数次迭代,在设计之初就应当考虑到用户将来各种可能的需求,应当在设计时就考虑到更多的情况,留下可扩展的空间。
- 掌握了多线程的基本方法和思想。但多线程的知识显然远不止课堂中学到的这些,还有许多知识值得探索。
五、改进建议:
- 在第一单元感觉还是过于没有准备,pre如果能够涉及一些更深的知识可能会更好
- UML图感觉可以提前一点将,之前没有学UML图却要画UML图,有很多错误但却不知道
- 关于测试以及junit的用法感觉可以多讲一些