OO第13-14次作业总结

面向对象第13-14次作业总结博客

1、设计分析

这个单元是我做的最差的一个单元。总工程量超过2000行(有效代码量1200左右),但两次都炸掉。

1.1、第13次作业--UML类图的解析

根据给定的UML类图部分内容,解析出关于类、方法、属性的相关信息。需要考虑继承等细节。

这是面向对象和容器类选择的综合考量。

架构上,首先实现对外接口。其次,对不同的UML元素采取不同处理:对于类,自定义一个ClassInfo类,存放和类相关的信息,比如父类、实现的接口、属性、方法等;对于接口,直接列一个邻接表,存放extends的接口。其它元素,表示的是类的成员和关系,做其他处理。架构设计没有任何思维难度。

另外,就是题目要求用类名、方法名、属性名等查找,所以要区分id和name,并采取不同的索引容器。大量用HashMapHashSet。这样可以根据contains系列检查存在性,根据size系列检查唯一性。

最难的地方,在于以下几个命令:实现的所有接口;属性查找(考虑继承);关联(考虑继承)。考虑继承,就需要设计一个递归的结构,和递归的处理方法。另外就是,为了保证效率,在查找后缓存在类信息中,便于重复查找。

这次本来很稳当的,最容易错的地方都专门考虑和测试了。但是,没想到错在一个指导书语焉不详的地方:属性可见性检查,需要输出属性名+类名。这个类名,是原始类名的意思,而不是提供的classname。虽说语焉不详,但是这种错误的根源在我,没有张口去问,想当然。

UML类图

image

复杂度分析

方法

Method ev(G) iv(G) v(G)
ClassInfo.addAssociation(String,boolean) 1.0 2.0 2.0
ClassInfo.addAttr(UmlAttribute,String) 1.0 3.0 4.0
ClassInfo.addInterface(String,String) 2.0 2.0 2.0
ClassInfo.addOperation(UmlOperation) 1.0 2.0 2.0
ClassInfo.addPara(UmlParameter) 2.0 2.0 3.0
ClassInfo.ass() 1.0 1.0 1.0
ClassInfo.ClassInfo(String) 1.0 1.0 1.0
ClassInfo.getAssList() 1.0 1.0 1.0
ClassInfo.getAssSet() 1.0 1.0 1.0
ClassInfo.getAttributes() 1.0 1.0 1.0
ClassInfo.getAttributeVisibility(String) 3.0 1.0 3.0
ClassInfo.getClassName() 1.0 1.0 1.0
ClassInfo.getInterfaceIds() 1.0 1.0 1.0
ClassInfo.getInterfaceMap() 1.0 1.0 1.0
ClassInfo.getInterfaces() 1.0 1.0 1.0
ClassInfo.getNotHiddenList() 1.0 1.0 1.0
ClassInfo.getNumOfAss() 1.0 1.0 1.0
ClassInfo.getNumOfAttr() 1.0 1.0 1.0
ClassInfo.getNumOfSelfAttr() 1.0 1.0 1.0
ClassInfo.getOperations() 1.0 1.0 1.0
ClassInfo.getOptCnt(OperationQueryType) 2.0 2.0 2.0
ClassInfo.getSuperClassId() 1.0 1.0 1.0
ClassInfo.getTopClassId() 1.0 1.0 1.0
ClassInfo.getTopClassName() 1.0 1.0 1.0
ClassInfo.hasInterfacesCompleted() 1.0 1.0 1.0
ClassInfo.isInterfacesCompleted() 1.0 1.0 1.0
ClassInfo.isSuperAssIncluded() 1.0 1.0 1.0
ClassInfo.isSuperAttrIncluded() 1.0 1.0 1.0
ClassInfo.isSuperInterfaceIncluded() 1.0 1.0 1.0
ClassInfo.setAssList(LinkedList) 1.0 1.0 1.0
ClassInfo.setNumOfAss(int) 1.0 1.0 1.0
ClassInfo.setSuperClassId(String) 1.0 1.0 1.0
ClassInfo.setTopClassId(String) 1.0 1.0 1.0
ClassInfo.setTopClassName(String) 1.0 1.0 1.0
ClassInfo.superHasAssIncluded() 1.0 1.0 1.0
ClassInfo.superHasAttrIncluded() 1.0 1.0 1.0
ClassInfo.superHasInterfaceIncluded() 1.0 1.0 1.0
MyUmlInteraction.addAss(UmlAssociation) 1.0 3.0 3.0
MyUmlInteraction.addAssociationEnd(UmlElement) 1.0 1.0 1.0
MyUmlInteraction.addAttribute(UmlElement) 1.0 2.0 2.0
MyUmlInteraction.addClass(UmlElement) 1.0 2.0 2.0
MyUmlInteraction.addGen(UmlGeneralization) 1.0 2.0 2.0
MyUmlInteraction.addInterface(UmlElement) 1.0 1.0 1.0
MyUmlInteraction.addInterfaceGroup(ClassInfo) 2.0 4.0 5.0
MyUmlInteraction.addOpt(HashMap,String) 1.0 2.0 2.0
MyUmlInteraction.addParam(UmlParameter) 1.0 2.0 2.0
MyUmlInteraction.addRealization(UmlInterfaceRealization) 1.0 1.0 1.0
MyUmlInteraction.addSuperAss(String) 2.0 3.0 4.0
MyUmlInteraction.addSuperAttr(String) 2.0 4.0 5.0
MyUmlInteraction.addSuperInterface(String) 1.0 3.0 3.0
MyUmlInteraction.checkException(String) 3.0 1.0 3.0
MyUmlInteraction.findTopClass(String) 2.0 3.0 3.0
MyUmlInteraction.getClassAssociatedClassList(String) 1.0 3.0 3.0
MyUmlInteraction.getClassAssociationCount(String) 1.0 1.0 1.0
MyUmlInteraction.getClassAttributeCount(String,AttributeQueryType) 4.0 4.0 4.0
MyUmlInteraction.getClassAttributeVisibility(String,String) 1.0 1.0 1.0
MyUmlInteraction.getClassCount() 1.0 1.0 1.0
MyUmlInteraction.getClassOperationCount(String,OperationQueryType) 1.0 1.0 1.0
MyUmlInteraction.getClassOperationVisibility(String,String) 1.0 3.0 3.0
MyUmlInteraction.getImplementInterfaceList(String) 1.0 2.0 2.0
MyUmlInteraction.getInformationNotHidden(String) 1.0 1.0 1.0
MyUmlInteraction.getTopParentClass(String) 2.0 1.0 2.0
MyUmlInteraction.MyUmlInteraction(UmlElement...) 3.0 8.0 17.0
Total 80.0 104.0 123.0
Average 1.27 1.6507936507936507 1.95

Class OCavg WMC
ClassInfo 1.30 48.0
MyUmlInteraction 2.88 75.0
Total 123.0
Average 1.95 61.5

细节越多,复杂度越大。这次考虑的细节非常之多,越写越堆积。所以,架构设计还是非常重要的,一不小心就超行数。把ClassInfo类独立出来是一个明智的选择。

1.2、第14次作业--类图、顺序图、状态图的解析

类图延续了上次的。于是,bug修复之后,以为这次会简单,谁知指导书自相矛盾,越写越陷入了循环迭代。提问区反复提问才搞清楚情况。自己菜没办法。OO炸四次,总成绩能不能上80还说不准呢。大学第一个70分的课程就要这样诞生了吗。听说,往届一般有40%的人是90+,大部分的人只炸一次,甚至一次不炸。唉,这课算学的彻底失败了。这门课也决定了这学期绩点不仅不能弥补上学期,反而比上学期更烂。

这次又需要检查合法性。这三个检查函数是老大难,差不多有400行左右的代码是关于有效性检查的。

无论怎样,来说说架构设计。依然是,类、状态机、时序图定义自己的Info类。Class MyInteraction extends MyClassInteraction implements Interaction,也就是继承上次的类图解析类,避免直接复制。

最难的就是有效性检查。首先是重名问题。这个简单。循环继承,也简单,dfs找强连通分量(或者直接找环)。难中之难是这个Uml009,也就是重复继承。不仅要检查接口重复继承,还要检查类实现接口的这种问题。就错在这个函数上,全军覆没。我觉得其它问题,都是

其实方法也没有思考难度,仅仅是求类实现的所有接口,以及接口继承的所有接口。但问题就在于如何保证不重复。由于循环继承的问题已经排除,所以最好的办法就是自顶向下。一旦发现重复就加入异常类/接口表中。

运是强者的谦辞,命是弱者的借口。承认自己的不足比什么都有用。工程能力并不是一朝一夕练就的,得到今天这个落魄下场,也全是我自己的过错,怪不得任何规则。

UML类图

image

复杂度分析

方法

Method ev(G) iv(G) v(G)
ClassInfo.addAssociation(String,String,boolean) 1.0 3.0 3.0
ClassInfo.addAttr(UmlAttribute,String) 1.0 3.0 4.0
ClassInfo.addInterface(String,String) 1.0 2.0 2.0
ClassInfo.addOperation(UmlOperation) 1.0 2.0 2.0
ClassInfo.addPara(UmlParameter) 2.0 2.0 3.0
ClassInfo.ass() 1.0 1.0 1.0
ClassInfo.ClassInfo(String) 1.0 1.0 1.0
ClassInfo.getAssList() 1.0 1.0 1.0
ClassInfo.getAssSet() 1.0 1.0 1.0
ClassInfo.getAttributes() 1.0 1.0 1.0
ClassInfo.getAttributeVisibility(String) 3.0 1.0 3.0
ClassInfo.getClassName() 1.0 1.0 1.0
ClassInfo.getInterfaceIds() 1.0 1.0 1.0
ClassInfo.getInterfaceMap() 1.0 1.0 1.0
ClassInfo.getInterfaces() 1.0 1.0 1.0
ClassInfo.getNotHiddenList() 1.0 1.0 1.0
ClassInfo.getNumOfAss() 1.0 1.0 1.0
ClassInfo.getNumOfAttr() 1.0 1.0 1.0
ClassInfo.getNumOfSelfAttr() 1.0 1.0 1.0
ClassInfo.getOperations() 1.0 1.0 1.0
ClassInfo.getOptCnt(OperationQueryType) 2.0 2.0 2.0
ClassInfo.getSuperClassId() 1.0 1.0 1.0
ClassInfo.getTopClassId() 1.0 1.0 1.0
ClassInfo.getTopClassName() 1.0 1.0 1.0
ClassInfo.hasAssName(String) 1.0 1.0 1.0
ClassInfo.hasInterfacesCompleted() 1.0 1.0 1.0
ClassInfo.isDup() 1.0 1.0 1.0
ClassInfo.isInterfacesCompleted() 1.0 1.0 1.0
ClassInfo.isSuperAssIncluded() 1.0 1.0 1.0
ClassInfo.isSuperAttrIncluded() 1.0 1.0 1.0
ClassInfo.isSuperInterfaceIncluded() 1.0 1.0 1.0
ClassInfo.setAssList(LinkedList) 1.0 1.0 1.0
ClassInfo.setNumOfAss(int) 1.0 1.0 1.0
ClassInfo.setSuperClassId(String) 1.0 1.0 1.0
ClassInfo.setTopClassId(String) 1.0 1.0 1.0
ClassInfo.setTopClassName(String) 1.0 1.0 1.0
ClassInfo.superHasAssIncluded() 1.0 1.0 1.0
ClassInfo.superHasAttrIncluded() 1.0 1.0 1.0
ClassInfo.superHasInterfaceIncluded() 1.0 1.0 1.0
MachInfo.addState(UmlElement) 1.0 3.0 4.0
MachInfo.addTrans(String,String,boolean) 1.0 3.0 4.0
MachInfo.getStateNum() 1.0 1.0 1.0
MachInfo.getSubNum(String) 3.0 2.0 3.0
MachInfo.getTransNum() 1.0 1.0 1.0
MachInfo.MachInfo(String) 1.0 1.0 1.0
MachInfo.subBfs(String) 2.0 3.0 4.0
MyUmlClassInteraction.addAss(UmlAssociation) 1.0 3.0 3.0
MyUmlClassInteraction.addAssociationEnd(UmlElement) 1.0 1.0 1.0
MyUmlClassInteraction.addAttribute(UmlElement) 1.0 2.0 2.0
MyUmlClassInteraction.addClass(UmlElement) 1.0 2.0 2.0
MyUmlClassInteraction.addGen(UmlGeneralization) 1.0 3.0 3.0
MyUmlClassInteraction.addInterface(UmlElement) 1.0 1.0 1.0
MyUmlClassInteraction.addInterfaceGroup(ClassInfo) 2.0 3.0 4.0
MyUmlClassInteraction.addOpt(HashMap,String) 1.0 2.0 2.0
MyUmlClassInteraction.addParam(UmlParameter) 1.0 2.0 2.0
MyUmlClassInteraction.addRealization(UmlInterfaceRealization) 1.0 1.0 1.0
MyUmlClassInteraction.addSuperAss(String) 2.0 3.0 4.0
MyUmlClassInteraction.addSuperAttr(String) 2.0 4.0 5.0
MyUmlClassInteraction.checkException(String) 3.0 1.0 3.0
MyUmlClassInteraction.classAddSuperInterface(String) 1.0 3.0 3.0
MyUmlClassInteraction.findTopClass(String) 2.0 3.0 3.0
MyUmlClassInteraction.getClassAssociatedClassList(String) 1.0 3.0 3.0
MyUmlClassInteraction.getClassAssociationCount(String) 1.0 1.0 1.0
MyUmlClassInteraction.getClassAttributeCount(String,AttributeQueryType) 4.0 4.0 4.0
MyUmlClassInteraction.getClassAttributeVisibility(String,String) 1.0 1.0 1.0
MyUmlClassInteraction.getClassCount() 1.0 1.0 1.0
MyUmlClassInteraction.getClassMap() 1.0 1.0 1.0
MyUmlClassInteraction.getClassOperationCount(String,OperationQueryType) 1.0 1.0 1.0
MyUmlClassInteraction.getClassOperationVisibility(String,String) 1.0 3.0 3.0
MyUmlClassInteraction.getElementMap() 1.0 1.0 1.0
MyUmlClassInteraction.getImplementInterfaceList(String) 1.0 2.0 2.0
MyUmlClassInteraction.getInformationNotHidden(String) 1.0 1.0 1.0
MyUmlClassInteraction.getInterfaceDup() 1.0 1.0 1.0
MyUmlClassInteraction.getInterfaces() 1.0 1.0 1.0
MyUmlClassInteraction.getTopParentClass(String) 2.0 1.0 2.0
MyUmlClassInteraction.interfaceAddSuper(String) 2.0 7.0 7.0
MyUmlClassInteraction.MyUmlClassInteraction(UmlElement...) 3.0 8.0 17.0
MyUmlGeneralInteraction.addInter(UmlElement) 1.0 1.0 1.0
MyUmlGeneralInteraction.addMach(UmlElement) 1.0 1.0 1.0
MyUmlGeneralInteraction.addTrans(UmlTransition) 1.0 1.0 1.0
MyUmlGeneralInteraction.checkForUml002() 2.0 5.0 6.0
MyUmlGeneralInteraction.checkForUml008() 2.0 9.0 9.0
MyUmlGeneralInteraction.checkForUml009() 6.0 12.0 12.0
MyUmlGeneralInteraction.classDfs(String,HashSet,HashSet) 2.0 4.0 4.0
MyUmlGeneralInteraction.getIncomingMessageCount(String,String) 1.0 1.0 1.0
MyUmlGeneralInteraction.getMessageCount(String) 1.0 1.0 1.0
MyUmlGeneralInteraction.getParticipantCount(String) 1.0 1.0 1.0
MyUmlGeneralInteraction.getStateCount(String) 1.0 1.0 1.0
MyUmlGeneralInteraction.getSubsequentStateCount(String,String) 1.0 1.0 1.0
MyUmlGeneralInteraction.getTransitionCount(String) 1.0 1.0 1.0
MyUmlGeneralInteraction.interException(String) 3.0 2.0 3.0
MyUmlGeneralInteraction.interfaceDfs(String,HashSet,HashSet) 2.0 4.0 4.0
MyUmlGeneralInteraction.machException(String) 3.0 2.0 3.0
MyUmlGeneralInteraction.MyUmlGeneralInteraction(UmlElement...) 2.0 3.0 10.0
MyUmlGeneralInteraction.retFromRecur(String,HashSet) 1.0 3.0 3.0
MyUmlGeneralInteraction.tempAdd(UmlElement,HashMap>) 1.0 2.0 2.0
SeqInfo.addMsg(UmlMessage) 1.0 2.0 2.0
SeqInfo.addObj(UmlLifeline) 1.0 2.0 2.0
SeqInfo.getIncome(String) 3.0 2.0 3.0
SeqInfo.getMsgNum() 1.0 1.0 1.0
SeqInfo.getObjNum() 1.0 1.0 1.0
SeqInfo.SeqInfo(String) 1.0 1.0 1.0
Total 138.0 196.0 230.0
Average 1.35 1.92 2.25

Class OCavg WMC
ClassInfo 1.31 51.0
MachInfo 2.57 18.0
MachInfo.StateInfo 0.0
MyUmlClassInteraction 2.68 83.0
MyUmlGeneralInteraction 3.21 61.0
SeqInfo 1.67 10.0
Total 223.0
Average 2.19 37.17

耦合度分析

ClassInfo 0.0 0.0 0.0 2.0 4.0
MachInfo 0.0 1.0 1.0 1.0 3.0
MachInfo.StateInfo 0.0 0.0 0.0 1.0 4.0
MyUmlClassInteraction 0.0 1.0 1.0 1.0 3.0
MyUmlGeneralInteraction 1.0 4.0 5.0 2.0 2.0
SeqInfo 1.0 1.0 5.0 1.0 2.0
Total
Average 0.33 1.17 2.0 1.33 3.0

2、架构总结、测试

架构:

第一单元多项式,使用了抽象类和类的递归结构。重点运用了方法重写。

第二单元多线程,了解了单例模式和工厂模式。会运用锁和同步。

第三单元图算法,了解了多重容器的使用,类的解耦。另外就是利用类的继承进行迭代开发。

第四单元UML,依然是迭代开发。接口独立,算法和容器开类封装。

其实越到后面,OO方法的选择,是一个自然而然的事情,并没有特意去思考哪一种设计模式,哪一种架构,而是根据需求。需求是一切设计的出发点和落脚点。甚至说,哪一种设计模式,我连名字听都没听说过,但是,一说大意,立马就知道自己用过。

测试:

第一单元使用对拍器,借助Python的数学工具。

第二单元改装定时输入接口。借用别人的special judge。

第三单元学会了Junit。

第四单元,手造类图+随机命令+对拍。

尤其是Junit的学习,受益匪浅。虽然依然隐藏着不明bug,但是,至少Junit的使用可以让我避免一些无脑错误。

测试手段也是一个循序渐进的过程。从最初像OJ题那样的对拍,到Junit等工具。测试的目的并不是证明自己没有错误,而是发现自己的错误。但并不是所有错误都可以通过测试检查出来。只有缜密的设计思维,才能从根本上避免错误。测试仅仅是针对自己的实现层面易错的地方进行,不能解决设计层面的纰漏。我这两个单元的惨败,就是因为设计思维的漏洞,用错误测试错误。

3、课程收获和建议

收获

最初步的收获,就是Java用得滚瓜烂熟。

第一单元,初步的“编译原理”。重点是类的迭代结构。继承和多态,这是所有OO设计的基础。

第二单元,把多线程摸了个门清。这是游戏体验最好的一个单元。

第三单元,复习了图算法。

第四单元,大工程量下的压力测试。并没有助教说的很简单,其实每年的最后一个单元都是大boss级别。

总的收获就是,OO设计模式的了解,以及算法、工程能力的提升。虽然这个课的作业写的很失败,但并不代表没用。

看到知乎上,有好多往届人故意攻击OO课程的,我觉得,他们就是像我这样炸过好几次作业的人,不懂得从自身分析问题,而去怪罪课程规则。我并没有标榜我的高尚,而是觉得他们这种键盘侠非常“睿智”。

这门课的体系还是非常好的,只不过,美中不足的地方在于指导书的自恰性不足,有好多有歧义的话,有可能有两种完全不同的实现。我能理解,指导书设计过程中,有好多难以全面考虑的地方,我们设计程序会犯错误,为什么不能设身处地想一下助教设计指导书也会有错误呢?毕竟,这种实验类的课程,助教也在为了精品作业而殚精竭虑。他们也有自己的课程,并不是全职服务员。

另外这门课的结果,也是我的反面教材,深刻的教训就是,一切设计都要有缜密的思维,方方面面都必须考虑清楚。只有这样才能得心应手。

建议

1、比如测试数据,至少提供一组强测数据,针对我们可能的错误来做自我检查。

2、编写指导书的时候,尽量考虑语言上的歧义情况,以及测试标准,数据限制等等。

3、在烤漆的作业,能否减少工程量,可以更多精力投入烤漆(不过这一点,我觉得其实可以忽略,因为总有人可以完成,物竞天择适者生存,我完不成我就应该接受被淘汰的结果。如果一门课让所有人都拿高分,这门课反倒没意义,我这么建议,对能完成的人实际上并不公平)。

我想对自己说的话:OO已结束,新征程将要开启。无论过去的结果如何,都已经成为过去。以史为鉴面向未来,相信失败乃成功之母。

posted @ 2019-06-24 21:48  wancong  阅读(322)  评论(3编辑  收藏  举报