OO第四单元总结
作业架构
第一次作业
- 类图:

- 度量分析:
| method | CogC | ev | iv | v |
|---|---|---|---|---|
| Association.addAssociationEnd(AssociationEnd) | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.Association(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getAssociationEndHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getEnd1() | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getEnd2() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.AssociationEnd(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getAggregation() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getMultiplicity() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getReference() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Attribute.Attribute(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Attribute.getType() | 0.0 | 1.0 | 1.0 | 1.0 |
| Attribute.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Class.Class(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Class.equals(Object) | 3.0 | 3.0 | 2.0 | 4.0 |
| Element.Element(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.getId() | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.getName() | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.getParentId() | 0.0 | 1.0 | 1.0 | 1.0 |
| Generalization.Generalization(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Generalization.getSource() | 0.0 | 1.0 | 1.0 | 1.0 |
| Generalization.getTarget() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addAssociation(Association) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addAttribute(Attribute) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addContainInterface(Interface) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addGeneralization(Generalization) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addInterfaceRealization(InterfaceRealization) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addOperation(Operation) | 1.0 | 1.0 | 2.0 | 2.0 |
| Interface.countVisibility(String) | 9.0 | 6.0 | 2.0 | 6.0 |
| Interface.getAssociationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getAttributeHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getContainInterface() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getGeneralization() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getGeneralizationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getInterfaceRealizationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getOperationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.Interface(UmlElement) | 2.0 | 1.0 | 2.0 | 2.0 |
| InterfaceRealization.getSource() | 0.0 | 1.0 | 1.0 | 1.0 |
| InterfaceRealization.getTarget() | 0.0 | 1.0 | 1.0 | 1.0 |
| InterfaceRealization.InterfaceRealization(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Main.main(String[]) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.examineAttribute(Attribute) | 12.0 | 6.0 | 12.0 | 15.0 |
| MyUmlInteraction.examineParameter(Parameter,String,String) | 12.0 | 6.0 | 12.0 | 15.0 |
| MyUmlInteraction.examineReturn(Parameter,String,String) | 12.0 | 6.0 | 13.0 | 16.0 |
| MyUmlInteraction.extract(UmlElement) | 11.0 | 10.0 | 11.0 | 11.0 |
| MyUmlInteraction.getClassAssociatedClassList(String) | 6.0 | 3.0 | 4.0 | 6.0 |
| MyUmlInteraction.getClassAttributeCount(String) | 3.0 | 3.0 | 2.0 | 4.0 |
| MyUmlInteraction.getClassAttributeType(String,String) | 9.0 | 6.0 | 3.0 | 9.0 |
| MyUmlInteraction.getClassAttributeVisibility(String,String) | 8.0 | 5.0 | 4.0 | 8.0 |
| MyUmlInteraction.getClassCount() | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassOperationCount(String) | 2.0 | 3.0 | 1.0 | 3.0 |
| MyUmlInteraction.getClassOperationParamType(String,String) | 15.0 | 8.0 | 5.0 | 8.0 |
| MyUmlInteraction.getClassOperationVisibility(String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| MyUmlInteraction.getImplementInterfaceList(String) | 3.0 | 3.0 | 2.0 | 4.0 |
| MyUmlInteraction.getInformationNotHidden(String) | 11.0 | 3.0 | 6.0 | 8.0 |
| MyUmlInteraction.getTopParentClass(String) | 4.0 | 4.0 | 2.0 | 5.0 |
| MyUmlInteraction.MyUmlInteraction(UmlElement...) | 1.0 | 1.0 | 2.0 | 2.0 |
| MyUmlInteraction.organize() | 37.0 | 5.0 | 20.0 | 20.0 |
| MyUmlInteraction.queryAssociation(String,HashSet,Association) | 4.0 | 2.0 | 3.0 | 4.0 |
| Operation.addParameter(Parameter) | 0.0 | 1.0 | 1.0 | 1.0 |
| Operation.getParameterHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Operation.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Operation.Operation(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Parameter.getDirection() | 0.0 | 1.0 | 1.0 | 1.0 |
| Parameter.getType() | 0.0 | 1.0 | 1.0 | 1.0 |
| Parameter.Parameter(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Total | 167.0 | 134.0 | 157.0 | 201.0 |
| Average | 2.4925373134328357 | 2.0 | 2.343283582089552 | 3.0 |
-
需求分析:
- 作业要求实现根据类mdj文件的内容输入,对UML模型解析。
- mdj文件输入格式为json,输入解析部分虽然说由官方完成,但是想要写UML模型分析,首先还是要去看官方的代码包。
- 我们最关心的问题在于官方代码解析出了什么,以便于我们能在java程序内使用。
- 可以看到所有输入都被解析为继承自UmlElement的各种UML模型元素,特别需要注意到的是他们都有一个查询对象真实类别的方法。而传给我们的解析器的是一个UmlElement数组。
-
架构设计:
- 有了之前的分析,不难想到对传入的UmlElement数组逐个判定类别,就可以确定输入的元素类型。
- 构建方法需要对UML模型本身有一定的知识。由于mdj中模型元素之间有着树状的组织,不少同学表示想用id和parentId造一颗树出来。
- 个人思考后觉得不采取树形构建,原因在于,虽然mdj中有类似树状的组织方式,但是实际上,每种元素之间的层层包含关系都是固定的,在作业的一些特殊规定下更是如此。
- 因此,我选择对每一种UML元素都构建一个自己对应的类。对UmlElement数组元素逐个检索,先判断元素类型,分类后再通过元素包含关系从底向上解析,构建自己的UML模型。
-
程序BUG分析:
-
没有被测出bug。
-
但是有待优化:第一次作业中interaction类代码超过了500行...很显然,查询的逻辑应该分派到一个类中完成,interaction中只需要接受答案即可。有了这样的反思,在之后的作业中代码架构就又有所改进。
-
第二次作业
- 类图:

- 度量分析:
| method | CogC | ev | iv | v |
|---|---|---|---|---|
| Association.addAssociationEnd(AssociationEnd) | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.Association(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getAssociationEndHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getEnd1() | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getEnd2() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.AssociationEnd(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getAggregation() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getMultiplicity() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getReference() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Attribute.Attribute(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Attribute.getType() | 0.0 | 1.0 | 1.0 | 1.0 |
| Attribute.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Class.Class(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Class.equals(Object) | 3.0 | 3.0 | 2.0 | 4.0 |
| ClassMod.examineAttribute(Attribute) | 12.0 | 6.0 | 12.0 | 15.0 |
| ClassMod.examineParameter(Parameter,String,String) | 12.0 | 6.0 | 12.0 | 15.0 |
| ClassMod.examineReturn(Parameter,String,String) | 12.0 | 6.0 | 13.0 | 16.0 |
| ClassMod.getClassAssociatedClassList(String) | 6.0 | 3.0 | 4.0 | 6.0 |
| ClassMod.getClassAttributeCount(String) | 3.0 | 3.0 | 2.0 | 4.0 |
| ClassMod.getClassAttributeType(String,String) | 9.0 | 6.0 | 3.0 | 9.0 |
| ClassMod.getClassAttributeVisibility(String,String) | 8.0 | 5.0 | 4.0 | 8.0 |
| ClassMod.getClassCount() | 0.0 | 1.0 | 1.0 | 1.0 |
| ClassMod.getClassOperationCount(String) | 2.0 | 3.0 | 1.0 | 3.0 |
| ClassMod.getClassOperationParamType(String,String) | 15.0 | 8.0 | 5.0 | 8.0 |
| ClassMod.getClassOperationVisibility(String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| ClassMod.getImplementInterfaceList(String) | 3.0 | 3.0 | 2.0 | 4.0 |
| ClassMod.getInformationNotHidden(String) | 11.0 | 3.0 | 6.0 | 8.0 |
| ClassMod.getTopParentClass(String) | 4.0 | 4.0 | 2.0 | 5.0 |
| ClassMod.organize() | 37.0 | 3.0 | 20.0 | 20.0 |
| ClassMod.queryAssociation(String,HashSet,Association) | 4.0 | 2.0 | 3.0 | 4.0 |
| Element.Element(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.getId() | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.getName() | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.getParentId() | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.setName(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| Event.Event(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Generalization.Generalization(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Generalization.getSource() | 0.0 | 1.0 | 1.0 | 1.0 |
| Generalization.getTarget() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interaction.addLifeline(Lifeline) | 1.0 | 1.0 | 2.0 | 2.0 |
| Interaction.getIncomingMessageCount(String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| Interaction.getParticipantCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interaction.getSentMessageCount(String,String,MessageSort) | 5.0 | 3.0 | 2.0 | 5.0 |
| Interaction.Interaction(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addAssociation(Association) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addAttribute(Attribute) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addContainInterface(Interface) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addGeneralization(Generalization) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addInterfaceRealization(InterfaceRealization) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addOperation(Operation) | 1.0 | 1.0 | 2.0 | 2.0 |
| Interface.countVisibility(String) | 9.0 | 6.0 | 2.0 | 6.0 |
| Interface.getAssociationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getAttributeHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getContainInterface() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getGeneralization() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getGeneralizationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getInterfaceRealizationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getOperationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.Interface(UmlElement) | 2.0 | 1.0 | 2.0 | 2.0 |
| InterfaceRealization.getSource() | 0.0 | 1.0 | 1.0 | 1.0 |
| InterfaceRealization.getTarget() | 0.0 | 1.0 | 1.0 | 1.0 |
| InterfaceRealization.InterfaceRealization(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.addReceive(Message) | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.addSend(Message) | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.getReceive() | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.getSend() | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.Lifeline(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Main.main(String[]) | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.addFromAndTo(Lifeline,Lifeline) | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.getFrom() | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.getMessageSort() | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.getSource() | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.getTarget() | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.getTo() | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.Message(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.extractClass(UmlElement) | 11.0 | 10.0 | 11.0 | 11.0 |
| MyUmlInteraction.extractState(UmlElement) | 15.0 | 6.0 | 12.0 | 12.0 |
| MyUmlInteraction.extractTime(UmlElement) | 7.0 | 4.0 | 6.0 | 6.0 |
| MyUmlInteraction.getClassAssociatedClassList(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassAttributeCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassAttributeType(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassAttributeVisibility(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassCount() | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassOperationCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassOperationParamType(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassOperationVisibility(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getImplementInterfaceList(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getIncomingMessageCount(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getInformationNotHidden(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getParticipantCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getSentMessageCount(String,String,MessageSort) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getStateCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getSubsequentStateCount(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getTopParentClass(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getTransitionTrigger(String,String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.MyUmlInteraction(UmlElement...) | 1.0 | 1.0 | 2.0 | 2.0 |
| MyUmlInteraction.organize() | 0.0 | 1.0 | 1.0 | 1.0 |
| Operation.addParameter(Parameter) | 0.0 | 1.0 | 1.0 | 1.0 |
| Operation.getParameterHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Operation.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Operation.Operation(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Parameter.getDirection() | 0.0 | 1.0 | 1.0 | 1.0 |
| Parameter.getType() | 0.0 | 1.0 | 1.0 | 1.0 |
| Parameter.Parameter(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Region.addEnd(State) | 0.0 | 1.0 | 1.0 | 1.0 |
| Region.addInitial(State) | 0.0 | 1.0 | 1.0 | 1.0 |
| Region.addState(State) | 1.0 | 1.0 | 2.0 | 2.0 |
| Region.getStateHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Region.getSubsequentStateCount(String,String) | 8.0 | 3.0 | 5.0 | 7.0 |
| Region.getTransitionTrigger(String,String,String) | 11.0 | 6.0 | 4.0 | 9.0 |
| Region.Region(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| State.addTrans(Transition) | 0.0 | 1.0 | 1.0 | 1.0 |
| State.getTransHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| State.State(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMachine.addRegion(Region) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMachine.getStateCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMachine.getSubsequentStateCount(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMachine.getTransitionTrigger(String,String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMachine.StateMachine(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMod.getStateCount(String) | 2.0 | 3.0 | 1.0 | 3.0 |
| StateMod.getSubsequentStateCount(String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| StateMod.getTransitionTrigger(String,String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| StateMod.organize() | 20.0 | 1.0 | 13.0 | 13.0 |
| TimeMod.getIncomingMessageCount(String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| TimeMod.getParticipantCount(String) | 2.0 | 3.0 | 1.0 | 3.0 |
| TimeMod.getSentMessageCount(String,String,MessageSort) | 2.0 | 3.0 | 1.0 | 3.0 |
| TimeMod.organize() | 8.0 | 1.0 | 6.0 | 6.0 |
| Transition.addEvent(Event) | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.addFrom(State) | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.addTo(State) | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getEventHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getFrom() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getSource() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getTarget() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getTo() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.Transition(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Total | 257.0 | 237.0 | 274.0 | 342.0 |
| Average | 1.822695035460993 | 1.6808510638297873 | 1.9432624113475176 | 2.425531914893617 |
-
需求分析:
- 扩展解析器,新添对UML状态图和顺序图的分析。
- 查看官方代码包,可以发现新增加的元素类型。
-
架构设计:
- 对照官方代码包的元素类型建立自己的类。
- 仍然采取对UmlElement数组元素检索,逐层构建。
- 需要注意的是,与类图不同,顺序图和状态图的模型可能在多个图内,因此最顶层要从图级别开始。
- 除此之外我认为这也是对不同类别图封装的提示,在图级别之上再加一级解析器类,实现一类图一个解析器,把查询方法从interaction里分派下来,优化架构。
-
程序BUG分析:抛异常不但要注意顺序,好好读题,因为你还可能读漏了....比如:
检测状态与迁移异常时,先检测起点状态是否存在异常,再检测终点状态是否存在异常,最后检查是否存在相应的迁移。就没检查对端的是我了。
第三次作业
- 类图:

- 度量分析:
| method | CogC | ev | iv | v |
|---|---|---|---|---|
| Association.addAssociationEnd(AssociationEnd) | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.Association(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getAssociationEndHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getEnd1() | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getEnd1Object() | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getEnd2() | 0.0 | 1.0 | 1.0 | 1.0 |
| Association.getEnd2Object() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.AssociationEnd(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getAggregation() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getMultiplicity() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getReference() | 0.0 | 1.0 | 1.0 | 1.0 |
| AssociationEnd.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Attribute.Attribute(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Attribute.getType() | 0.0 | 1.0 | 1.0 | 1.0 |
| Attribute.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Checker.Checker(HashMap,HashMap) | 0.0 | 1.0 | 1.0 | 1.0 |
| Checker.checkForUml001() | 2.0 | 2.0 | 2.0 | 3.0 |
| Checker.checkForUml002() | 8.0 | 5.0 | 5.0 | 6.0 |
| Checker.checkForUml003() | 7.0 | 5.0 | 4.0 | 5.0 |
| Checker.checkForUml004() | 9.0 | 5.0 | 5.0 | 6.0 |
| Checker.dfs(Interface,Interface,Set,Set) | 8.0 | 3.0 | 4.0 | 4.0 |
| Checker.dfs2(Interface,Interface,Set,HashMap) | 5.0 | 1.0 | 4.0 | 4.0 |
| Checker.mergeInterface(HashMap,HashMap) | 6.0 | 1.0 | 4.0 | 4.0 |
| Class.Class(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Class.equals(Object) | 3.0 | 3.0 | 2.0 | 4. |
| ClassMod.examineAttribute(Attribute) | 15.0 | 7.0 | 11.0 | 15.0 |
| ClassMod.examineParameter(Parameter,String,String) | 15.0 | 7.0 | 11.0 | 15.0 |
| ClassMod.examineReturn(Parameter,String,String) | 15.0 | 7.0 | 12.0 | 16.0 |
| ClassMod.getClassAssociatedClassList(String) | 6.0 | 3.0 | 4.0 | 6.0 |
| ClassMod.getClassAttributeCount(String) | 3.0 | 3.0 | 2.0 | 4.0 |
| ClassMod.getClassAttributeType(String,String) | 9.0 | 6.0 | 3.0 | 9.0 |
| ClassMod.getClassAttributeVisibility(String,String) | 8.0 | 5.0 | 4.0 | 8.0 |
| ClassMod.getClassOperationCount(String) | 2.0 | 3.0 | 1.0 | 3.0 |
| ClassMod.getClassOperationParamType(String,String) | 15.0 | 8.0 | 5.0 | 8.0 |
| ClassMod.getClassOperationVisibility(String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| ClassMod.getImplementInterfaceList(String) | 3.0 | 3.0 | 2.0 | 4.0 |
| ClassMod.getInformationNotHidden(String) | 11.0 | 3.0 | 6.0 | 8.0 |
| ClassMod.getTopParentClass(String) | 4.0 | 4.0 | 2.0 | 5.0 |
| ClassMod.organize1() | 26.0 | 6.0 | 14.0 | 15.0 |
| ClassMod.organize2() | 16.0 | 1.0 | 8.0 | 8.0 |
| ClassMod.queryAssociation(String,HashSet,Association) | 4.0 | 2.0 | 3.0 | 4.0 |
| Element.Element(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.getId() | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.getName() | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.getOrigin() | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.getParentId() | 0.0 | 1.0 | 1.0 | 1.0 |
| Element.setName(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| Event.Event(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Generalization.Generalization(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Generalization.getSource() | 0.0 | 1.0 | 1.0 | 1.0 |
| Generalization.getTarget() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interaction.addLifeline(Lifeline) | 1.0 | 1.0 | 2.0 | 2.0 |
| Interaction.getIncomingMessageCount(String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| Interaction.getParticipantCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interaction.getSentMessageCount(String,String,MessageSort) | 5.0 | 3.0 | 2.0 | 5.0 |
| Interaction.Interaction(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addAssociation(Association) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addAssociationEndTarget(AssociationEnd) | 2.0 | 2.0 | 2.0 | 3.0 |
| Interface.addAttribute(Attribute) | 2.0 | 2.0 | 2.0 | 3.0 |
| Interface.addContainInterface(Interface) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addGeneralization(Generalization) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addInterfaceRealization(InterfaceRealization) | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.addOperation(Operation) | 1.0 | 1.0 | 2.0 | 2.0 |
| Interface.checkR001() | 3.0 | 1.0 | 3.0 | 3.0 |
| Interface.countVisibility(String) | 9.0 | 6.0 | 2.0 | 6.0 |
| Interface.getAssociationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getAttributeHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getContainInterface() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getGeneralization() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getGeneralizationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getInterfaceRealizationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getOperationHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Interface.Interface(UmlElement) | 2.0 | 1.0 | 2.0 | 2.0 |
| InterfaceRealization.getSource() | 0.0 | 1.0 | 1.0 | 1.0 |
| InterfaceRealization.getTarget() | 0.0 | 1.0 | 1.0 | 1.0 |
| InterfaceRealization.InterfaceRealization(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.addReceive(Message) | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.addSend(Message) | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.getReceive() | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.getRepresent() | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.getSend() | 0.0 | 1.0 | 1.0 | 1.0 |
| Lifeline.Lifeline(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Main.main(String[]) | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.addFromAndTo(Lifeline,Lifeline) | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.getFrom() | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.getMessageSort() | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.getSource() | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.getTarget() | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.getTo() | 0.0 | 1.0 | 1.0 | 1.0 |
| Message.Message(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.checkForUml001() | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.checkForUml002() | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.checkForUml003() | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.checkForUml004() | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.checkForUml005() | 1.0 | 2.0 | 1.0 | 2.0 |
| MyUmlInteraction.checkForUml006() | 1.0 | 2.0 | 1.0 | 2.0 |
| MyUmlInteraction.checkForUml007() | 6.0 | 4.0 | 3.0 | 5.0 |
| MyUmlInteraction.checkForUml008() | 8.0 | 4.0 | 6.0 | 7.0 |
| MyUmlInteraction.extractClass(UmlElement) | 13.0 | 10.0 | 12.0 | 12.0 |
| MyUmlInteraction.extractState(UmlElement) | 15.0 | 6.0 | 12.0 | 12.0 |
| MyUmlInteraction.extractTime(UmlElement) | 7.0 | 4.0 | 6.0 | 6.0 |
| MyUmlInteraction.getClassAssociatedClassList(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassAttributeCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassAttributeType(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassAttributeVisibility(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassCount() | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassOperationCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassOperationParamType(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getClassOperationVisibility(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getImplementInterfaceList(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getIncomingMessageCount(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getInformationNotHidden(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getParticipantCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getSentMessageCount(String,String,MessageSort) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getStateCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getSubsequentStateCount(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getTopParentClass(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.getTransitionTrigger(String,String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| MyUmlInteraction.MyUmlInteraction(UmlElement...) | 1.0 | 1.0 | 2.0 | 2.0 |
| MyUmlInteraction.organize() | 1.0 | 1.0 | 1.0 | 2.0 |
| MyUmlInteraction.throwR005(String) | 2.0 | 1.0 | 1.0 | 3.0 |
| Operation.addParameter(Parameter) | 0.0 | 1.0 | 1.0 | 1.0 |
| Operation.getParameterHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Operation.getVisibility() | 0.0 | 1.0 | 1.0 | 1.0 |
| Operation.Operation(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Parameter.getDirection() | 0.0 | 1.0 | 1.0 | 1.0 |
| Parameter.getType() | 0.0 | 1.0 | 1.0 | 1.0 |
| Parameter.Parameter(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Region.addEnd(State) | 0.0 | 1.0 | 1.0 | 1.0 |
| Region.addInitial(State) | 0.0 | 1.0 | 1.0 | 1.0 |
| Region.addState(State) | 1.0 | 1.0 | 2.0 | 2.0 |
| Region.getStateHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Region.getSubsequentStateCount(String,String) | 8.0 | 3.0 | 5.0 | 7.0 |
| Region.getTransitionTrigger(String,String,String) | 11.0 | 6.0 | 4.0 | 9.0 |
| Region.Region(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| State.addTrans(Transition) | 0.0 | 1.0 | 1.0 | 1.0 |
| State.getLast() | 0.0 | 1.0 | 1.0 | 1.0 |
| State.getTransHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| State.State(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMachine.addRegion(Region) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMachine.getStateCount(String) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMachine.getSubsequentStateCount(String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMachine.getTransitionTrigger(String,String,String) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMachine.StateMachine(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| StateMod.getStateCount(String) | 2.0 | 3.0 | 1.0 | 3.0 |
| StateMod.getSubsequentStateCount(String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| StateMod.getTransitionTrigger(String,String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| StateMod.organize() | 20.0 | 1.0 | 13.0 | 13.0 |
| TimeMod.getIncomingMessageCount(String,String) | 2.0 | 3.0 | 1.0 | 3.0 |
| TimeMod.getParticipantCount(String) | 2.0 | 3.0 | 1.0 | 3.0 |
| TimeMod.getSentMessageCount(String,String,MessageSort) | 2.0 | 3.0 | 1.0 | 3.0 |
| TimeMod.organize() | 8.0 | 1.0 | 6.0 | 6.0 |
| Transition.addEvent(Event) | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.addFrom(State) | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.addTo(State) | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getEventHashMap() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getFrom() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getGuard() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getSource() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getTarget() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.getTo() | 0.0 | 1.0 | 1.0 | 1.0 |
| Transition.Transition(UmlElement) | 0.0 | 1.0 | 1.0 | 1.0 |
| Total | 344.0 | 293.0 | 330.0 | 416.0 |
| Average | 2.072289156626506 | 1.7650602409638554 | 1.9879518072289157 | 2.5060240963855422 |
-
需求分析:
- 要对完成解析的图做有效性检查。
- 首先需要看好官方包代码结构:他是在解析完输入后,构造interaction,然后会依次调用几个有效性检查。
- 这一点很重要,如果不要求依次调用,一者作业要求会有矛盾冲突,二者你可以随意安插检查顺序(主要是安插在解析过程中)。
- 但是要求了检查顺序后,最好按照顺序来。
-
架构设计:
- 构建自己的对于类的优势就在于,随时根据需求可以适当改造类成员属性。如R001就可以在class里加入一个查重用的hashmap,在每次调用addAttribute和AddAssociation的时候就往这个表里加名称。
- 注意null不算重名。(没错这个问题卡了我一个点,我不重名因为我没名字 lol )
- 判断循环继承,重复继承,重复实现。比较规矩的办法是dfs,作业时空要求很宽泛, 不必优化也能过。不过这里还是有一些架构上的技巧可以用,其实在第一次作业里,对于查询类实现的接口这种问题,我就直接在类和接口里定义了一个类实现的接口字段,每当发生继承和接口实现的时候,就把类或者接口对应的实现的接口addAll进去。当然,输入是乱序的肿么办呢?那就直接把解析方法循环做继承元素加接口实现元素次(跑。
- 虽然听起来很奇怪,但是方法最多是O(nm)的复杂度,实际中方法数和继承实现数会互相牵制,也不比dfs差。
- 最后,其实还是可以在解析元素类别的时候检查R005之类的规则,但是不能在这时候直接抛异常,稳妥的办法是先标记一下,之后按顺序检查的时候回去查这个标记,如果有再抛出。
-
程序BUG分析
- CPU运行时离超出还差得远,出现了神奇的RTLE,第一反应是回想起多线程的作业输入结束时间线比较靠后的情况。最后果然还是dfs没写好....
四个单元架构设计及OO方法理解演进
第一单元
- 最开始对于架构没什么概念,唯一慌的地方在于java不是很熟悉,感觉预习内容锻炼的基础能力是代码实现的重要保障。
- 如果说当时有那么一点
出于可拓展性的考虑,就是没有自己想技巧来解析,而是直接查资料认真学习了递归下降算法,方便了之后几次作业都一直沿用这个算法逻辑。 - 架构基本还是面向过程的思路,只是凭着感觉按照表达式的各个构成要素拆分包装成了类。直到几次理论课过后,才有了设计类,通过类的协作描述程序,通过继承和实现接口对共享数据和共享行为抽象等,对于oo方法有了基础的理解,也开始进一步改造自己的作业架构。
第二单元
- 第二单元开始,经过课程组的引导,我接触了大量的面向对象模型,学习模型并不断尝试把问题抽象成对应相应模型,更加深化了我面向对象的思想。
- 多线程电梯的作业,我不再仅是因为感性的认识去划分电梯类,调度器类,而是真实的看到了他们作为类独立存在的必要。认识到了程序功能的实质是对象之间交互和管理共享数据。
- 作业中生产者消费者模式是我的主要架构,为了能更清晰的表示电梯的状态和行为,我也尝试了引入状态模式。
- 而对于保护线程安全问题,简单的wait和notify已经显现出了一些弊端:应该考虑notify先被执行而后执行wait的情况,很容易导致死锁。为此我又研究了semaphone,它的优点在于release是增加请求次数,可以再被acquire消耗。以及探索用单例模式解决线程安全问题。
- 经过第二单元的学习,我对于OO的思想以及从熟悉简单的面向对象规则上升到了学习和运用面向对象的经典模型。
第三单元
- 第三单元一开始给人的感觉是按图索骥,完全照着JML翻译代码,不禁会让人怀疑是否还有所谓的架构存在。但是在实现的具体过程中,完全照着代码翻译却在测试中疯狂超时。因为JML的精髓就在于,只
给出规格。规格并不完全是直接可以拿去生产的蓝图,他在蓝图之上,用比自然语言更加严谨的描述,对各处的实现给出具体的要求,而不限定具体的实现方法。一如大自然规定森严的科学法则,却不限制万物自由生长尽显百态。我们拿到要求后,第一时间仍是要做出自己的架构设计,来满足规格的要求。 - 由此,为了满足时间要求。我的架构中嵌入了多层次的缓存机制,为查询操作节约时间。对于图算法的部分,又采用了并查集,优先队列优化的最短路算法,不断精简算法,提高处理速度。
- 而且需要注意的是,在课程组的训练计划里,实际上不止希望我们能看懂JML,还要会写JML。我个人认为拿着别人写好的规格做实现和拿到问题书写规格是不同层次的锻炼,制定规则需要我们运用JML的语法规则解析自然语言问题,按规则办事在架构上花费的心思可能要更多。
- 经过第三单元的学习,我对于OO的设计思想的理解更进一步:问题的抽象思维过程,首先要把问题落实到严谨规则上,明确目的,在通过面向对象构造来实现。
第四单元
- 第一次听说UML还是在第一单元的总结博客,当时对于画类图的要求不明所以。现在回首,用建立模型的方法分析自己的程序,可以清楚的看到自己程序的体系结构。图上形形色色的符号,清楚地表示了程序中类的基本结构,类与类之间的结构关系。
- 课程组采用书写UML模型解析器的方式,带动我们深入学习UML语言,本身是很有创意的,兼顾了图形化层面和代码层面的掌握UML。但是个人感觉从模型图到模型的语言还是有一定跨度的,网上教程偏向于图的内容更多,语言方面的知识更多都是我课上学习以及在课下研究mdj文件摸索出来的。
- 正是由于仔细研究了UML描述的mdj文件的格式,才让我选择放弃树形架构,选择了分类架构,类与类关联的方式组织数据,省去了树形结构大面积的插入查找代码,用更简单的实现方式完成了作业。
- 经过第四单元的学习,我对于OO的设计思想跳出了程序的局限,开始更多从模型的角度审视面对的问题以及架构的设计。
四个单元测试理解与实践演进
- 从机组一路走过来,我知道充足的测试可以给自己带来的自信心,但是每次都要重写一遍测试规则,增加额外的工作,让我对于测试还是很苦恼。在写第一单元第一次作业的时候还在疯狂手动构造样例,以及读代码肉眼debug。这个问题在互测的时候体现的很明显,是所谓"被对方机械化大军屠杀"。无奈第二次作业做完后,终于下决心写了自己的测试数据生成器,能够按需随机生成数据,并且实现对拍。基于这次成果,从此我的OO测试终于走上了自动化的道路(x
- 然而多线程里的自动化测试又遭一劫。如何定点投放输入,如何精确bug复现等难题纷纷上线,借助讨论区同学的方法,以及OS课程的一些知识,我把评测机又包装了一下,通过命令行操作提高了自动化的程度。当然,阅读代码仍然是多线程debug的一大法宝。除此之外,Jprofile工具也在多线程debug发挥了一定作用。
- 之后的作业里,又有了Junit的帮助。通过编写和运行可重复的测试,对类的行为进行测试,减轻了我构造测试环节的压力。
课程收获
从基础语法都把握不全,到现在能熟练的写出千行的作业代码。自己不仅仅是熟悉了一门语言,更是收获了面向对象分析问题,设计方案,解决问题的思维。想到第一单元作业每次重构的痛苦与艰辛,再到之后三个单元能够复用代码,真正做到迭代开发的轻松愉快。强测也让我克服惰性,终于尝试了自己造数据,造评测机,用各种工具测试。在OO课程一分耕耘,一分收获永远是我美好的回忆。
课程建议
- 可以参考机组,做一个公众号,通知有关课程平台的消息。或者定期把讨论区的精品贴集中做个推送。
- training的内容貌似有一段时间没有跟上进度。

浙公网安备 33010602011771号