第四单元
OO第四单元博客
摘要
第四单元是设计一个类图解析器,将官方包预处理好的UML图元素进行解析,并执行相关的查询指令。
架构设计
总体来说,第四单元的难度适中,但是涉及到了很多类的交互,编程时需要有很清晰的思路和架构,层次化设计的概念在这个单元得以体现。
层次
架构设计层次如下类图:
建立模型添加元素时,在对应的模型中,新建对应的UML对象并添加到Parent元素的属性中。
执行查询指令时,自顶向下,从MyImplementation
类将指令逐级下发。最终,类图查询指令主要在MyReference
完成,状态图查询指令主要在MyStateMachine
中完成,时序图查询指令主要在MyCollaboration
中完成。
数据结构
考虑到UML元素输入时不能保证顺序 ,所以在建立模型时就应将一些对象保存到容器中,部分数据结构如下:
private final HashMap<String, MyClass> id2Class = new HashMap<>();
private final HashMap<String, MyClass> name2Class = new HashMap<>();
private final HashMap<String, MyState> id2State = new HashMap<>();
private final HashMap<String, MyLifeLine> id2Lifeline = new HashMap<>();
private final HashMap<String, UmlLifeline> id2UmlLifeline = new HashMap<>();
算法设计
三次作业的主要算法都是和接口的多继承相关,所以算法都是使用了DFS。并且在每次搜索之后,在类/接口中设置脏位,并保存搜索到的元素,之后再次查询时就可以直接返回结果,不用再次搜索。部分代码实现如下:
private boolean flag = false;
public HashMap<String, MyInterface> getClassImplementInterfaceList() {
if (flag) {
return getName2Interface();
}
HashMap<String, MyInterface> myInterfaceHashMap = new HashMap<>();
myInterfaceHashMap.put(getName(), this);
for (MyInterface myInterface : superInterfaces) {
myInterfaceHashMap.putAll(myInterface.getClassImplementInterfaceList());
}
flag = true;
setName2Interface(myInterfaceHashMap);
return myInterfaceHashMap;
}
架构设计思维&OO方法理解
-
第一单元在进行设计时,架构设计时没有充分考虑可拓展性,类的协作方式写得很复杂,三次作业都进行重构。从三次作业,我也意识到了的架构设计的重要性,感受到了面向对象和过去的面向过程的差异性和便捷性。
-
第二单元虽然是多线程,但架构设计仍然是不可或缺的。我从实验代码的架构中学到了很多,将线程安全通过生产者-消费者模式融入到了架构设计中。架构设计为拓展功能做足的准备,在后续的作业中真正感受到了迭代的快乐。
-
第三单元是JML,主要以规格化的阅读理解为主,架构已经被固定下来了,主要工作是数据结构的设计和算法的实现。
-
第四单元是UML解析。UML图中的元素较多,关系图也比较复杂,层次化设计的概念在这个单元得以充分展现,通过自顶向下的设计,在后续迭代的过程中减少了很多工作量。
总体而言,通过OO课程的学习,我对面向对象的设计思想和程序架构的设计有了更深的理解。
测试总结
第一单元
测试数据主要都是手动构造,复杂的数据通过Matlab对拍。
第二单元
测试数据使用了Python随机生成,利用cmd投喂数据,由于评测逻辑较为复杂,没有使用自动测试。
第三单元
测试数据使用Python随机生成,并且手动构造了一些边界数据,与同学对拍测试。
第四单元
测试数据生成较为困难,只用手动的方式绘制了一些UML图进行测试。
总体而言,代码的测试工作做得还是不够充分,强测中还是错误频现,希望能够利用暑假的时间提升自己的覆盖性分析能力和程序测试能力。
课程收获
一个学期的OO课程,学习到的成体系的知识包括面向对象的设计思想和设计模式、多线程的设计思想、JML和UML的阅读理解。此外,一整个学期的面向对象课程,带来了的是整体的能力的提升:
-
编程能力的提升。从程序设计的几十行代码,到数据结构的一两百行代码,再到OO的每周千行代码,在不断实践的过程中,编程能力取得了很大的进步。
-
架构设计能力的提升。每个单元作业都是迭代完成的,在不断的迭代设计中,更加体会到了架构设计的重要性。在最初设计架构时,就要充分考虑架构的可拓展性和可维护性,并且架构要是层次清晰,各个部分功能明确,这样可以很大程度上避免重构。
-
设计思想上的提升。Java和以往的C语言不同,这是一门面向对象语言,编程的基本单位从函数变成了类,逐渐适应了封装、继承、多态、抽象等面向对象特性。在类的协作、交互上有了更深的理解。
-
测试能力的提升。虽然自动测试做得不多,但总归还是动手编写了部分作业的python自动测试代码。看到博客中很多同学的测试总结中都提到了测评机的搭建,我还是有点遗憾的吧,希望可以利用暑假的时间,利用oo作业回炉练习一下程序测试的能力。
-
设计模式的学习。在OO课程中,提到了工厂模式、生产者消费者模式等诸多面向对象设计模式,对我的编程风格和架构设计都产生了很多积极影响。
改进建议
从整个学期来说,OO课程还是很人性化的(没有占用假期时间),老师和助教团队也能及时给我们答疑解惑。就个人体会上来说,我有如下的改进意见:
-
阅读好的代码。建议新增一个代码阅读环节,每个单元给一些助教大佬的代码,供我们阅读比较,取长补短(互测中的代码我们也不好判断代码质量)。
-
有关protected修饰符的使用。之前吴老师已经在群里回答过这个问题,通过private关键字对数据进行保护是很有必要的。但是随着课程的进行,代码量逐渐增大,我们对Java语言的使用也日渐熟练,因此,我建议可以考虑在课程中段逐步放开对protected修饰符的使用。
-
难度跨度较大。前两个单元的作业完成地都很艰难,建议可以适当增加寒假Pre的内容并且提早发布每个单元的Training。
-