Final Summary
Final Summary
写在前面:由于撰写本文时正处考期,时间较为紧张,很多内容没有展开来谈,深表遗憾。
第四单元三次作业架构设计
总体架构:用MyElement
管理每个(任何类型的)UML元素,其中存储儿子、父亲、关联对端、继承与实现的目标、状态转移的目标状态、生命线接受的信息等。在MyUmlInteraction
交互类中,用HashMap<ElementType, HashMap<String, MyElement>>
管理各种类型的MyElement
。
public class MyElement {
private final UmlElement element;
private MyElementsManager sons = new MyElementsManager();
private HashMap<String, UmlAssociationEnd> associations = new HashMap<>();
private HashMap<String, MyElement> generalizations = new HashMap<>();
private HashMap<String, MyElement> implementations = new HashMap<>();
private HashMap<String, UmlTransition> transitionsTo = new HashMap<>();
private HashMap<String, UmlMessage> messagesRecv = new HashMap<>();
private MyElement parent;
...
}
第二次作业及第三次作业中,由于元素类型增多,对不同元素的访问需求越来越复杂,因此引入元素管理器类MyElementsManager
,提供增加元素、按照指定类型获取该类型所有元素、按照指定id获取该元素的功能接口,为每个UML元素管理所有儿子和总交互类管理所有元素提供服务。这样的好处是,无需按照不同的元素类型分开管理,只需要处理时取出相应类型的元素即可。
public class MyElementsManager {
private HashMap<ElementType, HashMap<String, MyElement>> elements =
new HashMap<ElementType, HashMap<String, MyElement>>() {{
for (ElementType type: ElementType.values()) {
put(type, new HashMap<>());
}
}};
public MyElement findElementById(String id) { ... }
public HashMap<String, MyElement>
findAllElementsByType(ElementType... types) {
...
}
public void add(MyElement newElement) { ... }
public HashMap<String, MyElement> getAllElements() { ... }
}
第三次作业增加了检查功能,但大多数都由交互类和元素类负责实现,导致单个类代码较长;这也是使用元素管理统一管理带来的副作用。但总体来看,代码复杂度和算法复杂度都较低,除了第一次由于架构过于简单导致一个点TLE之外,都没有bug。
四个单元架构设计及OO方法理解的演进
总体来看,四个单元架构设计的进步,主要体现在动手设计之前会更加考虑到后续的迭代,从而使用更加可维护且可增加功能的架构。例如,第一单元第二次作业就对第一次作业的架构进行了完全的推倒重构,是所有作业中工作量最大的一次;后续几次作业中,整体架构都比较稳定,没有出现大规模重构,可以说是有所进步。个人认为,架构设计最稳定的是第二单元的多线程电梯,三次作业的架构基本没有变化。三四单元的架构也相对稳定,每次都只有小修小补。
至于OO方法的理解,我认为第一单元教会我们的就足够了,即继承、多态等经典的OO概念;运用这些概念是十分自然的,这也是书写OO的代码给我们带来的快感所在。在每个单元的总结中,我们都会对工程的一些OO参数进行查看和反思;通过查看这些参数,有助于我们理解OO的设计应该是什么样的,例如“高内聚 低耦合”等等,可以说是让我们从自己的代码中理解OO的思想。
四个单元中测试理解与实践的演进
四个单元了,还是不会写自动测试脚本,也没有用成相关的自动生成测试用例的工具。
测试的方法总体来看还是比较粗暴的,前两个单元主要是根据理解,手动构造一些简单但有价值的样例;第三单元可以生成一些随机数据和同学的进行对拍;第四单元则主要是用实际的用例来进行测试。
这种测试简单,但只适合单线程程序;对于第二单元的多线程电梯,这样测试的难度较大。这也侧面反映出,对于程序的测试,主要还是要靠实际使用过程中的反馈;无论自己如何测试,也很难仅通过自行构造用例就发现所有的问题。
后面我们引入了JML、JUnit这样的工具来进行验证。从这些工具涉及的初衷来看,对开发程序的人员进行测试都有很大的帮助;但实际上我们也看到了,JML实际操作起来难度较大,使用体验也极差;JUnit虽然需要手动实现一些东西,但更加实用。坦白地说,我从来没有在作业中使用过相关的测试工具,只是在多线程debug中用到了相关的查看运行状态的工具,但我们必须正确认识这些工具的初衷带来的价值。尤其是JUnit使用的单元测试和覆盖性检查的思想,值得我们在今后的工程开发过程中使用。
课程收获
-
语言
学习并在一定程度上掌握了Java语言。这是学习本课程的最大收获。
-
多线程编程
此前从来没有接触过多线程编程,而OO课程为我们打开了新世界的大门。这也是最有价值的收获。
-
OO的思想
上文也提到过,OO的思想其实是显而易见的。本课程是让我们用最好的实践的方式,去运用了OO的知识,让我们在实践中收获了经验,可谓是实践出真知。
-
工程化思想
坦白来说,对工程化思想的训练,OO课程不如计算机组成课和操作系统课更有力;但必须承认,这是OO课训练的必然结果。
改进建议
- 互测机制不公平,不同room使用的hack用例不同。建议改room内hack为提供评测用例对所有人进行评测,将被hack的bug计入公测,并为提供有效测试用例的加分。
- 多线程评测结果不稳定,严重缺乏严谨性。对于一份代码,在同一个测试用例上,至少应时间间隔较远地进行多次测试,并取最终结果。
- 单次作业周期太短;建议在提交截止前至少两周(甚至是讲授相关课程内容前)就发布作业。
- 公布每次实验结果,并实验结束后进行讲解。
线上学习体会
听课能听得更清楚,但对于课上讨论和研讨课来说,效率就过低了。
线上学习终究只是一种应急的方式,对于OO这种知识很活、需要大家共同分享的科目来说,还是需要线下的学习。这学期OO还是有相当的遗憾。
posted on 2020-06-19 19:41 Stitch11752 阅读(265) 评论(0) 编辑 收藏 举报