OO面向对象编程:第四单元总结及课程总结

OO面向对象编程:第四单元总结及课程总结

 

 

 

一、第四单元作业架构

1.第一次作业

作业类图:

  1. 顶级类 MyUmlGeneralInteraction 负责将输入归类,形成3个子UmlElement数组,分配给处理类图,状态图和顺序的3个类;建立基础设施类:graph,实现图的通用方法:加边,dfs,计算可达结点,拓扑排序等。对于类图,类和接口都当作图中的结点;

  2. MyUmlClassModelInteraction处理类图,MyUmlCollaborationInteraction处理顺序图,MyUmlStateChartInteraction处理状态图,三者基于graph类;状态,迁移个数抽象成图的结点数和边数,后继状态抽象成计算图中某点的可达结点数; 参与对象,交互消息抽象成图的结点数和边数, incoming消息抽象成图中某个结点的入度; 有了图结构之后,类图中的函数实现也变得非常简单。比如计算类实现的全部接口实质,先做拓扑排序,再按照逆拓扑序依次计算每个结点实现的接口。这样一来,计算某个类时,其父类,以及其实现的接口实现的接口都已经算出来了,直接列表相加就行。不需要任何的递归。 建完3个图后,将所有的查询全部计算完毕缓存起来,之后查询只是访问缓存结果。

2.第二次作业

作业类图:

1 在第二次作业中我将功能更细致的拆出去。Graph类用来处理新增加的对状态图和顺序图的查询,Check类实现对类图 进行Rule1,Rule2,Rule3的查询,Build类服务于构造方法中对UMLElement的信息的初始存储,主类依旧完成对类图的先关查询,为了满足类不超过500行,对于与attribute有关的查询被单独放到了count类。拆类将功能更加细致的划分出去,但是更多的map结构在类之间传递也为写代码带来困扰,并且有一个类方法依赖的数据结构过多,最终传入9个参数,checkstyle没有过。

2 在第一次作业的基础上新增的查询状态图和查询顺序图的需求难度不大,在构造方法中把这两个图有关数据类型之间的关系保存下来,在getStateCount、getTransitionCount、 getParticipantCount、getMessageCount、 getIncomingMessageCount直接查询即可,getSubsequentStateCount中后继状态之间的关系类比多继承关系,用bfs解决也是轻车熟路。

Rule1就是对于已经存好信息的数据结构进行查询即可。对于Rule2,由于接口与类继承特性的区别,分别检查接口与类是否满足要求。对于循环继承,考虑进行dfs递归,我的初始版本dfs设计的不好,思路受限于哈密尔顿图的dfs算法,导致一些冗余重复的递归发生,对于继承分支多的接口检查时会超时。经过思考与同学讨论,意识到这个地方的dfs与哈密尔顿图的dfs要求有些许差别,因此实现上细节应该改进。对于Rule3,与检查类有几个接口的思路类似,使用bfs并适当缓存信息即可。

3.对UML的理解:总结与感受

统一建模语言(英语:Unified Modeling Language,缩写 UML)是非专利的第三代建模和规约语言。UML是一种开放的方法,用于说明、可视化、构建和编写一个正在开发的、面向对象的、软件密集系统的制品的开放方法。UML展现了一系列最佳工程实践,这些最佳实践在对大规模,复杂系统进行建模方面,特别是在软件架构层次已经被验证有效。

在UML系统开发中有三个主要的模型:

  • 功能模型:从用户的角度展示系统的功能,包括用例图。

  • 对象模型:采用对象,属性,操作,关联等概念展示系统的结构和基础,包括类别图、对象图。

  • 动态模型:展现系统的内部行为。包括序列图,活动图,状态图。

区分UML模型和UML图是非常重要的,UML图,包括用例图、协作图、活动图、序列图、部署图、构件图、类图、状态图,是模型中信息的图形表达方式,但是UML模型独立于UML图存在。UML的当前版本只提供了模型信息的交换,而没有提供图信息的交换。

UML使用一套与Java语言或其他面向对象语言等价物,同时也是本体论等价物的图形标记。

UML并不是一个方法学,也不要求使用一个方法学,但是UML对于Rational统一过程来说是必不可少的。

回顾本单元的设计训练:

• UML功能视图(use case diagram)支持的元素及关系表达 • 用例(use case):系统提供给用户的功能及其交互场景 • Precondition, postcondition, flow of events • 执行者(actor):为系统执行提供输入激励或者记录系统执行结果的相关 对象 • 自然人、设备、其他系统等 • actor与use case之间的关系 • 哪些用户为这个用例提供输入? • 哪些用户关心这个用例的执行结果? • use case与use case之间的关系 • 依赖关系 • 抽象层次关系

• 状态图针对具有一定状态复杂度的类来专门设计其行为 • 多种状态和转移关系 • 在运行时会随输入动态改变其状态 • 一般多用于描述控制行为:针对被控对象的状态来实施相应的控 制行为,并维护其状态更新 • 线程调度(线程对象的状态空间) • 根据线程对象的状态来调度请求来更改其状态 • 电梯调度(电梯对象的状态空间) • 根据电梯对象的状态来分配乘客请求并改变其状态 • 不同状态之间在属性取值上必须严格分离

 

二、课程总结

 

1.结构设计以及方法理解的演进

本学期OO课程,让我进入了面向对象编程的世界。在这个世界中,万物皆对象。没有什么new一个对象解决不了的问题,如果有,那就再new一个新的对象。说起来很简单,但是其中技巧非常之多。我们的面向对象程序需要具有高内聚,低耦合的特点,具有很强的复用性和扩展性。这需要我们充分理解并且合理运用JAVA封装,继承,多态这三个特点。封装为了程序的安全性,我们代码风格也要求我们进行合理的封装。而最关键的时继承和多态。通过继承,接口,重写等操作,会大大增强我们程序的可扩展性和复用性。

在第一单元表达式求导的作业中,我对面向对象的理解不足,程序非常的“面向过程”,主要体现在大量核心代码集中在一个类,甚至一个方法之中;类与类之间的耦合度很高,我在使用Metrics度量分析我的代码时,很多类复杂度爆红;代码的扩展性很差,三次作业我都进行了大面重构甚至重写。

经过第一单元作业的经验教训,在第二单元作业中,我非常重视代码的构架设计,注意类功能的内聚性,用包对不同功能的类进行了划分,并应用枚举类,单例模式,观察者模式等多种方法

让代码具有一定的扩展性。在三次增量式作业中,我的构架基本上可以支持扩展,让作业之间的迭代变得容易了很多。但是我对各种方法运用的还不够成熟,复杂度还是比较高

第四单元作业,我延续一学期以来学习面向对象的思想,使用了接口和继承对元素进行抽象,封装了一些数据结构,并对不同图的元素进行划分。保证了两次作业增量式设计,进一步锻炼了构架设计能力,让我对面向对象的思量有了更深的理解。

总体来说,经过了这学期以JAVA语言为载体的面向对象编程训练之后,我逐渐理解了面向对象建模思维的一般过程与方法,抛弃了以前面向过会曾编程的种种不好的习惯。

2.理解与实践的演进

在第一单元的测试中,着重测试了代码的正确性,其中主要针对边界条件进行测试,构造了大量的数据进行验证。由于数据的规模很小,没有对性能进行很好的测试。

第二单元是多线程的测试,由于多线程的特殊性,导致一些bug很难复现,不太容易找到程序中存在的bug,导致在面对一些特殊数据时,处理方法不够得当,出现了很多问题。

第三单元的JML实现中,虽然有自动测试的工具,但还是主要通过自己生成的数据进行测试。为了保证运行的正确性,针对每一条指令的每一个分支进行测试,尽量做到充分覆盖。而由于没有测试程序运行时间的措施,导致在第一次作业中对运行时间估计出错,大面积超时。

第四单元是UML的分析,测试主要通过自己构造UML模型来测试,针对于模型中的具体细节进行独立测试。在第二次作业状态图和顺序图的分析时,单独考虑两者的所有情况即可。而在三条规则性检查时,借助讨论区中的一些测试样例完成了测试。

在这四个单元中,课程组培养我们注重的不仅仅是代码书写和架构设计,还有对代码的测试也是一门重头戏。可以说,代码的测试是保证每份代码质量必不可少的一环,如果缺少了代码测试,相信很少有人能够信誓旦旦的保证自己的代码完全没有问题。课程组在第一单元的第一次作业就强调让我们重视代码的测试问题,鼓励我们对代码进行深度测试,尤其是在第三单元,我们学习了Junit对代码进行测试,这样能够基本保证代码的基本功能的可靠性。

 

3.课程收获

(1)封装

所谓“封装”,就是用一个框架把数据和代码组合在一起,形成一个对象。遵循面向对象数据抽象的要求,一般数据都被封装起来,也就是外部不能直接访问对象的数据,外部能见到的只有提供给外面访问的公共操作(也称接口,对象之间联系的渠道)。在C#中,类是对象封装的工具,对象则是封装的基本单元。

(2)继承

世界是复杂的,在大千世界中事物有很多的相似性,这种相似性是人们理解纷繁事物的一个基础。因数事物之间往往具有某种“继承”关系。比如,儿子与父亲往往有许多相似之处,因数儿子从父亲那里遗传了许多特性;汽车与卡车、轿车、客车之间存在着一般化与具体化的关系,它们都可以用继承来实现。

(3)多态性

多态性就其字面上的意思是:多种形式或多种形态。在面向对象编程中,多态是指同一个消息或操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。例如,问甲同学:“现在几点钟”,甲看一看表回答说:“3点15分”,又问乙同学:“现在几点钟”,乙想一想回答说:“大概3点多钟”,又问丙同学:“现在几点钟”,两干脆回答说:“不知道”。这就是同一个消息发给不同的对象,不同的对象可以做出不同的反应。

三、给课程的改进建议

我觉得这门课程整体的难度设置,各个单元的内容的连贯性都还不错,学习的主题也比较鲜明,作业相关内容的设置还有老师助教们为我们提供的优良的线上测试的平台的体验都是相当不错的。

有以下几点建议:

1.在寒假时可讷讷更需要自己去学习大量的java的语法知识,其中在预习的过程中,就有可能已经让我们去自学了大量的关于面向对象编程思想的知识,这对于我来说,在寒假没有进行大量相关工作,到了开课之后,感到对整体的要求同学对基本知识的掌握上有些不达标。

因此希望在预习阶段,老师能够给一些更加具体有效的预习建议,甚至是教程。

2.对于上课的实验部分,也就是上机,虽然主旨是让我们去学习,而非测验,但是每次早上刚刚介绍完本次学习的主题和重点之后,下午就直接去进行相关的测试,这就要求我们提前比较长的时间去准备,去了解之后的学习内容,所以对于一部分同学早上才了解了相关知识之后,下午就直接考试的话,可能会带来比较大的压力。

所以建议每次上了讲解知识之后,隔一段时间,再去进行上机这样的测试活动。

 

 

原文地址:https://www.cnblogs.com/chenhaonan-nickyoung/p/11078841.html