BUAA_OO_Unit4

BUAA_OO_Unit4

本单元需要实现一个UML解析器的核心功能。

一、架构设计

UML图的结构清晰,有着天然的层次化结构。所以可以直接按照UML内部的模块构建类结构。最终完成的结构如下:

下面分次介绍设计细节:

1.1 第十三次作业——建立类图

增加类MyClassDiagram,MyAssociation,MyClass,MyInterface,MyNameableType,MyOperation.

  • 数据的读入

使用多次遍历的方法读入数据,将具体加入过程封装在MyClassDiagram对象中。

public MyImplementation(UmlElement... elements) {
   classDiagram = new MyClassDiagram();
   addMacro(elements); //class, interface
   addMicro(elements); //attribute,operation,association,gen,interfaceReal
   addNano(elements);  //parameter, associationEnd
}

private void addNano(UmlElement[] elements) {
   for (UmlElement e : elements) {
       if (e instanceof UmlParameter) {
           classDiagram.addParameter((UmlParameter) e);
      } else if (e instanceof UmlAssociationEnd) {
           classDiagram.addAssEnd((UmlAssociationEnd) e);
      }
  }
}
  • 结构的建立

为便于执行指令,将官方包提供的UmlClass,UmlInterface等类的功能进行扩展,成为MyClass,MyInterface等类的属性。

private MyClass parent;
private ArrayList<UmlAttribute> attributes;
private HashMap<String, MyOperation> operations;
private HashMap<String, MyInterface> interfaces;      //implemented interfaces
private HashMap<String, MyAssociation> associations;  //associations with others
private UmlClass umlClass;
private ArrayList<MyClass> children;

private HashMap<String, String> implementInterfaceMap;
  • 指令的处理

为避免MyImplementation类过于臃肿冗长,将每一步操作都实现在下属的MyClass,MyInterface类中,只保留大的操作步骤,使得三次作业中MyImplementation类的代码行数始终控制在330行以内。

@Override
public int getClassAttributeCouplingDegree(String className)
       throws ClassNotFoundException, ClassDuplicatedException {
   MyClass myClass = classDiagram.getClass(className);
   return myClass.getAttrCouplingDegree(myClass.getId());
}

@Override
public List<String> getClassImplementInterfaceList(String className)
       throws ClassNotFoundException, ClassDuplicatedException {
   MyClass myClass = classDiagram.getClass(className);
   HashMap<String, String> resultMap = myClass.getImplementInterfaceMap();
   return new ArrayList<>(resultMap.values());
}

1.2 第十四次作业——建立顺序图、状态图

增加类MySequenceDiagram,MyStateDiagram,MyEndPoint,MyGeneralLifeline,MyInteraction,MyLifeline,MyRegion,MyState,MyStateMachine,MyTransition.

  • 顶层结构

本次作业建立起三种UML图的结构,在MyImplementation顶层类中只有三个属性:

private final MyClassDiagram classDiagram;
private final MySequenceDiagram sequenceDiagram;
private final MyStateDiagram stateDiagram;

类图的指令就调用MyClassDiagram的方法处理,其余两种图同理。

  • 降低类之间的耦合

为了保证类之间的低耦合,采用层层向内调用的方法,以getStateCount()为例:

//MyImplementation.java
public int getStateCount(String s)
           throws StateMachineNotFoundException, StateMachineDuplicatedException {
   MyStateMachine sm = stateDiagram.getStateMachine(s);
   return sm.getStateCount();
}

//MyStateMachine.java
public int getStateCount() {
   return region.getStateCount();
}

//MyRegion.java
public int getStateCount() {
   return states.size();
}
  • 关键状态的判断

本次作业最复杂的指令就是关键状态的判断指令。对此的实现为:

采用DFS遍历得到一个双层ArrayList保存从初始状态到最终状态的所有路径。

private ArrayList<ArrayList<MyState>> allPaths;

若某一状态在所有路径中,则该状态为关键状态。

1.3 第十五次作业——规范性验证

本次作业没有添加新的类.

  • 循环继承和重复继承

以接口的循环继承和重复继承为例,在MyInterface中定义递归方法,分别使用DFS向上遍历所有接口,第一次DFS当检测到和thisID相同的接口时说明有循环继承,第二次DFS当检测到当前遍历到的接口ID已经遍历过时,说明有重复继承。

二、架构设计思维及OO方法理解的演进

经过了十二次的代码训练,我对架构设计和OO思维都有了更深刻的理解。

第一单元时我还对OO思想所知甚少,基本上是面向实验代码编程,在整体编完后再反复阅读代码,才窥见到递归下降和表达式,项,因子层次化建模的精妙之处。方法复杂度的控制基本上全靠IDEA的Extract Method功能,都是先编好一个冗长的方法再去想办法精简,且顶层设计思维缺失,最后的metrics里复杂度居高不下,也花费了大量时间。

第二单元的多线程我以前从未接触过,理论课讲授JVM的线程原理时需要花一些时间才能理解,或许若是事先学习了OS的进程管理部分会更好理解一些。那时最常见的错误就是死锁,也就是在那时我初步学会了使用设计模式来让我的代码更加清晰。在不断调试的过程中,我逐渐明白了类之间的协作和解耦的意义。

第三单元JML主要要求不在于架构,而是细致读代码和算法复杂度的控制。JML虽然难以读懂,但一旦读懂基本不会出现正确性问题。这个单元的代码很值得学习,虽然不需要我们去设计,但编完代码再纵观全局,可以体会到好的架构设计带来的好处。

第四单元我的层次化设计思想有了很大地进步,开始主动地设计自己代码的层次、主动进行类的解耦。我真切地看到了自己OO思维和架构设计思维的提升。

三、测试理解与实践的演进

第一单元由于完成作业占用时间较多,没有尝试构建评测机和数据生成器,采用手动构造边界数据的方法进行测试,但由于覆盖性不够高,导致还是出现了bug。

第二单元构造了简易的数据生成器进行测试,检测到了一定数量的bug,但由于编写时考虑不周,仍未做到很高的覆盖率。

第三单元编写了数据生成器,实现了参数控制构造有针对性的数据,并和同学进行对拍,另外所幸本单元数据较为友好,数据覆盖率得到了很大的改善。

第四单元由于数据构造难度上升,采取手动构造UML图的方法。

四、课程收获

  • 建立了OO的思维,对代码架构的理解加深

  • 了解了多线程的基本原理和实现方法,可以进行一般的同步控制。

  • 了解了应用设计模式进行编程的重要性和好处。

  • 掌握了测试的重要性和一般方法,学会构造简易的数据生成器和对拍程序。

  • 提升代码能力、算法能力和复杂度优化能力。

  • 充分体会到多人合作编写程序时做好接口的重要性,例如在U4中不需了解很多的上层官方包代码就可以进行核心功能的开发,避免了重复开发引起的效率低下。

  • 切身实践了小型工程性代码的编写,这与之前的算法题和微型程序的编写步骤有一定区别。

  • 了解到面向对象的优势和Java作为一门纯粹的面向对象语言编写复杂程序时的魅力。

五、改进建议

  • 希望在第一单元之前做更多的铺垫,例如递归下降的介绍,个人认为第一单元难度跨度较大,即使完成了Pre,仍然在初次看到题时一头雾水。

  • 希望在课上实验后公布答案或者评测结果,这样能够更清楚地发现自身问题。

  • 给出一些数据测试的教程,第一二单元对测试还不够了解时不知道该从何下手编写评测机。

  • 希望后两个单元的理论课可以更加实际,个人感觉后两个单元的理论课和作业有些脱节,联系不够紧密。

posted @ 2022-06-26 17:11  LetsHurtTonight  阅读(17)  评论(2编辑  收藏  举报