OO_课程总结

一、第四单元架构设计

1.第一次作业

UML类图

OO_课程总结_第1张图片

本次作业中我的设计思路是将不同的元素分别交给不同的类来管理;同时考虑到之后可能会增加新的UML图,于是又单独增加了ClassDiagram这个类来表示UML类图,最终的程序架构如上图所示。我将属于类图的元素都交给ClassDiagram类统一管理,同时也把属于UMLClass的元素、属于UMLInterface的元素和属于UMLOperation的元素分别交给MyClass、MyInterface和MyOperation管理。此外增加了一个类ExTree来处理继承相关的问题。

算法方面主要涉及到继承相关的问题,我采取的是DFS+Cache的方式,在遍历过程中就把父类的相关元素交给子类,后续查询的时候子类可以直接给出结果。在处理接口继承的时候也是类似的思路。这些算法在ExTree类中完成。

MyUmlInteraction中的查询方法一部分被交给了ClassDiagram完成,另一部分交给了ExTree或MyClass完成。下面三个并不严格的顺序图说明了类与类之间的交互关系,其中call表示某个方法调用,return表示结果返回。

OO_课程总结_第2张图片

OO_课程总结_第3张图片

OO_课程总结_第4张图片

本次作业的架构设计我认为主要存在两点不合理之处:ClassDiagram并不必要去管理所有类图的元素;ExTree类的设置比较多余,其中的功能完全可以由其他类来完成。应该说在本单元自己对UML的理解还不够。

2.第二次作业

UML类图

本次作业的架构设计是按照如下两图所示的UML元素与元素之间的关系来进行的:

OO_课程总结_第5张图片

OO_课程总结_第6张图片

第一张图表示的是类图和状态图中的元素关系,第二张图则是顺序图中的元素关系。本次作业中每个UML元素都属于某个父元素并同时只管理属于自身的子元素,相比于第一次作业每个类的职责更加明确。个人感觉这样设计会使得整个程序编写变得很简单,相关的查询功能实现起来也更自然。本次作业在前一次的基础上增加了和状态图、顺序图相关的类,其他并无大的改动。

算法方面仍然是采取DFS+Cache的方式处理继承、接口实现统计以及子状态数计算。

本次作业中类与类之间的交互可以用下面的顺序图表示,Diagram表示某个UML图,Element表示属于该图的某个子元素:

OO_课程总结_第7张图片

OO_课程总结_第8张图片

3.第三次作业

本次作业架构并无改变,仅仅是增加了相应的一致性检查功能。

算法方面,由于我前两次作业在处理继承时使用的是DFS,因此此次在处理循环继承时使用了基于DFS实现的Tarjan算法求所有的继承环。其他的算法并无改变,仅是增加了一些对是否违背一致性原则的判断。

 

二、架构及OO方法理解演进

2.1 架构设计演进

第一单元

第一单元主要训练的是抽象与归一化处理的能力。在实现时需要按照自己的架构或处理流程设计来从输入中提取对象并处理,其中提取对象这一步就是体现架构设计的关键。该单元的训练内容在第三次作业中体现得很明显,因为这次作业的输入在定义上和结构上都是嵌套式的;解析这样的输入需要我们在输入的形式以及求导的基本规律这两个基础上提取出若干个具有代表性的对象(比如Item),这是抽象的过程;在后续处理时需要根据具体要求泛化出更具体的类型,但在处理这些具体类型时仍然是将其视作那个抽象对象来处理的,这是归一化处理的基本思路,在具体实现时可以使用继承的方式。

在第一单元第一次作业中初步尝试使用类的概念来设计程序,基于作业的需求设计了如常量、变量、项及多项式等类;在第二次作业中同样根据作业需要增加了三角函数类和相应的处理方法。由于第一次接触面向对象,在这两次作业设计中把注意力都放在了作业的要求而缺乏对抽象设计和可扩展性的考虑,导致在第三次作业中应用前两次的架构就存在许多问题,比如一个嵌套的函数就无法处理。第三次作业我主要围绕一个处理算法来设计架构,并没有在输入的形式上和求导的规律上去考虑,导致这样的架构实际上是很难扩展的,这样算是回到了面向过程吧。总而言之,第一单元初步接触和运用了面向对象的一些基本概念来设计架构,但是设计的基本功——抽象能力和方法却没有掌握,导致设计出来的架构可扩展性差。

第二单元

第二单元主要训练的是多线程编程、线程安全和线程通信。总体上看,在设计时需要明确线程与线程之间的关系以及线程与共享数据之间的关系,这些关系需要在架构设计的过程中进行层次化地划分。线程的设计需要从需求中抽象并明确功能模块与功能模块之间的划分,这一点可以从设计模式的角度来考虑;此外还需要考虑可扩展性要求。线程安全的实现需要去识别保护对象,并使得同步控制范围尽量小来提升性能。线程通信的过程至少需要考虑线程间如何传递信息、如何同步、如何处理线程间的依赖关系以及如何避免死锁等问题,具体如何处理这些问题仍然要根据所设计的架构来考虑。

由于在第一单元中的架构设计体验不佳,在第二单元中我学习了一些设计模式来帮助进行设计。本单元第一次作业明显属于生产者-消费者模式,可以很自然地提取出请求提供者(生产者)和电梯(消费者)两个线程;同时我考虑了功能的扩展,增加了一个调度器类负责安排请求,而电梯只需要负责自身的运行。第二次作业我仍将其视作生产者-消费者模型,直接沿用了第一次的架构,此外增加了一个类来辅助消息的处理;但是我在线程通信上做得不好,突出的一点是没考虑好死锁问题,导致在多个电梯线程运行时可能出现程序无法结束的情况。在第三次作业中我首先想到的是责任链模式,而实现时是在调度器类中生成请求链并交给不同电梯处理,主体仍然是请求提供者-电梯形成的生产者-消费者架构。总的来说,第二单元的架构设计过程中运用了设计模式以及对可扩展性的考虑,相比于第一单元有所进步,实际作业体验也更好;但架构的设计仍然有很多改进空间,比如调度器类对电梯线程的管理以及它们之间的交互等。

第三单元

第三单元在架构方面主要考察的是中间数据和数据模型的构建和协同。该单元的输入数据显然需要按照一定的结构进行组织,同时作业中许多方法都与最终性能有关,因此必须构建若干个数据结构来高效地处理问题。此外该单元的输入是对可以对数据进行增删改查的,因此还需要考虑数据模型的构造如何正确且高效,以及数据模型是否需要进一步建立若干层次以适应数据内容的变化。本单元的架构需要去解决数据模型设计以及它们之间协同的问题,从而实现在性能方面的要求。

第一次作业中对架构设计的要求小,我只考虑了图数据结构的建立,使用图来管理person和relation。第二次作业中沿用了图数据结构来管理数据;此外查询方法增多,为提高性能增加了若干中间数据缓存来动态维护查询结果,同时还新增了排序树结构求nameRank以及并查集结构来判断isCircle。第三次作业增加了更多中间数据缓存,并在第二次作业的数据结构中增加了若干方法;其中,一些数据结构可以用于中间数据缓存的更新,如并查集可以用来更新blockSum。总的来说,我在本单元中初步体会了通过适当的数据模型将性能要求融入架构设计的过程;但我所选择的数据模型比较零散,也没有考虑层次化的设计,整体的架构缺乏协同和扩展的能力。

第四单元

第四单元在架构方面主要涉及对象之间的层次关系和关联关系。程序首先需要对输入内容进行解析、对其中的对象进行提取,然后再将对象按照一定层次关系组织起来,这一般是整个架构设计的大概。在进行对象层次的架构设计时应该体现出UML模型的语义,并考虑对查询数据的动态维护。

我在本单元的架构设计如第一部分所述。这一单元我体验较多的是层次化的架构设计,这种设计让我对各个数据对象的组织变得得心应手。

架构设计演进总结

可以看到在本学期的作业练习中,我的架构设计大致经历了这样一个过程:第一单元的新手上路体验、第二单元的设计模式指导设计、第三单元的数据模型结合设计以及第四单元建立在UML规则上的层次化设计。前两个单元的演进过程主要是从摸索到运用一定的设计方法;而后两个单元我认为是在前两个单元的基础上作了不同方面的架构设计尝试;贯穿四个单元始终的我认为是一个抽象分析能力的提升。

2.2 OO方法理解演进

第一单元中我主要是对抽象、类、继承等这些OO的基本概念有一个了解和初步的尝试,但是由于缺乏设计经验和方法导致尝试过程中出现许多困难;同时OO中还强调模块化和可扩展性,我在第一单元中对此考虑较少,这也导致我对作业进行了一次重构。总的来讲,第一单元这个阶段我处于对OO方法的了解层次上,缺乏经验和基于实践的认识。

第二单元通过课程介绍我学习了设计模式,期间主要体会到了设计模式对软件设计方法的总结和抽象。同时该单元的作业也有所强调对设计模式的合理运用,所以在一单元我在设计模式的指导之下体会到了OO方法中提到的抽象、模块化等概念,自己开始有了一些设计的经验。此外由于作业结构设计还算得当,2、3次作业均在前一次作业的基础上迭代完成,所以对于可扩展设计也有了一定体会。

第三次作业加入了JML,进一步地了解到了DBC并学习了相关概念。回想起设计模式,我认为抽象归纳在OO方法中的地位很重要。对于DBC,我认为它是从软件设计和使用交互的角度去抽象,具体地归纳出前置条件、后置条件和不变式三个核心概念;对于设计模式,我认为其是对不同需求和软件架构设计这两个方面进行的抽象和归纳。此外,本单元作业的一个突出特点就是涉及到了很多算法和数据结构,如何在架构设计时考虑它们来实现性能上的要求也是一个很大的问题。我认为关键是对数据模型以及其行为的抽象,而在前几次作业中我主要体会的是在功能模块角度上的抽象。

第四单元围绕着UML的模型化设计展开。从作业中我感受较多的是层次化设计,而学习UML的过程中体会较多的是模型化的设计理念。

 

三、测试理解与实践

由于刚接触java和面向对象,我对第一单元的测试仍停留在大一那样对一个小程序测试的阶段,在构造样例时只是依据自己所想到的点,没有注重一定的方法和过程。这样构造的样例对程序的测试覆盖率不高,一些潜在的错误难以发现;即使发现了错误也往往难以定位,测试效率低。

在第二单元中的测试中我开始根据作业要求梳理需要测试的点,并针对不同的功能模块(比如电梯、调度器的某个调度逻辑等)单独构造样例并测试。这样的测试方法使我的测试效率有所提高,程序的质量也得到了进一步保证。但我在构造样例由于缺乏一定的方法而显得比较盲目,无法保证覆盖率。同时该单元涉及的是多线程而导致调试困难,同时我的程序中部分架构设计得不好,这两个原因导致有时查错拍错费时费力。
第三单元中我学习了如等价类法、因果图法等测试用例构造方法,在构造样例时盲目程度有所降低,结合着对程序的功能模块划分使测试效率进一步提高。但是我的程序仍然存在架构比较不合理的地方而导致正确地排错变得很困难,在公测中也因为模块间架构设计的问题导致了失分。

在第四单元的课堂学习中老师提到了程序架构设计的重要性以及测试对保证程序质量的辅助作用。结合之前作业中在架构上吃的亏,我开始重视架构设计,尽量做到在程序架构设计的过程中去最大程度减少错误。本单元中我参考UML元素间的关系来组织架构,个人感觉程序编写时十分容易,并且测试时排错效率大大提高。此外我还进一步了解了使用UML进行测试的基本方法,结合之前所学的测试用例构造方法进一步提高了对程序测试的覆盖率。

总的来讲,经过这四个单元的练习,我认为保证程序质量最重要的还是程序本身的架构设计,测试应该作为进一步地保证或辅助手段;其次,对于测试本身应该基于程序的架构并在一定方法的指导下进行,应尽量避免盲目性地开展测试。

 

四、课程收获总结

我认为一学期的课程学习一方面提升了我的编程能力,从需求分析、架构设计以及测试等方面已有了很大提升;另一方面、同时也是更为重要的一方面就是让我学会了许多设计思想。第一单元虽然是刚接触OO,但也让我对抽象和层次化设计有所体会。第二单元中最突出的就是多线程设计以及与其相关的许多概念;同时在这一单元我开始学习设计模式,了解了许多抽象设计思想。第三单元中接触了JML和DBC,其中蕴含的软件设计方法也很值得学习。第四单元中的UML则包含有许多模型化设计思想。四个单元虽然具体内容不尽相同,但在软件设计思想上我认为都是相通的,比如抽象化、结构化、层次化等。相信在课程中学习到的这些内容在未来的学习生活中会给予我很多指导。


五、课程改进建议

1.课程有时会有对指导书、实验等的更改通知,大部分通知都需要登录课程网站才能看到,这就导致有时学生可能会错过通知,所以可以改善下课程消息通知方式,方便大家及时知晓。

2.个人认为第二单元的内容可以放在后面,而把JML或UML的内容提前。因为这样可以先让大家对程序设计方法等方面有所学习和思考,否则如果在缺少设计经验的情况下就去完成多线程的内容会比较困难,程序设计质量也不好保证。

3.是否可以更多介绍一下程序性能与架构的关系以及相关设计方法。因为部分作业的性能对算法和数据模型设计有所要求,如何能把它们和程序整体架构结合在一起考虑我个人感觉比较困难,有时可能过分在意性能而导致不能按照自己最初的想法进行架构设计。

六、线上学习感受

感觉线上学习缺少互动和交流,有些问题不能得到及时解决。但线上学习使得时间安排可以自由些;同时由于录播课程的原因,老师讲授的内容可以多次去理解,上课的压力减小了许多。

你可能感兴趣的:(OO_课程总结)