UnitFourSummary
目录
- 第四单元架构设计
- taskOne
- taskTwo
- taskThree
- 四个单元架构设计与OO方法理解的演进
- 四个单元架构设计
- UnitOne
- UnitTwo
- UnitThree
- UnitFour
- 对OO方法理解的演进
- 四个单元架构设计
- 四个单元测试理解与实践的演进
- 课程收获
- 改进建议
- 线上学习OO课程的体会
第四单元架构设计
第四单元主体架构:manager架构
taskOne
因为在指令查询时,属性、操作、与哪些类关联三者之间不存在相关性,可以独立管理
所以为三者建立单独的管理者:AttributeManager
,OperationManager
,AssociationManager
同时抽象出共有方法,建立抽象类Manager
,三个具体的管理者是抽象类的具体实现
类与接口组成相似,所以继承同一个类MyClass
此时的MyClass
包含
- name、id、extends的内容、implements的内容
- AttributeManager
- OperationManager
- AssociationManager
指令查询与数据管理更为方便
同时设置ClassManager
,管理MyClass
,将查询指令的具体实现统一放在ClassManager
中,指令查询时MyUmlInteraction
只要调用ClassManager
的方法即可,防止未来因为要求在MyUmlInteraction
中实现的方法过多而过于臃肿
最终架构即为:
- MyUmlInteraction
- ClassManager
- MyClass自身信息
- AttributeManager
- OperationManager
- AssociationManager
- ClassManager
manager架构具有较强的兼容性,在增加新的查询需求时,只需建立对应的manager
即可
查询逻辑图:
UML图:
taskTwo
在manager架构下继续扩充,添加stateManager
和InteractManager
用来管理状态图和顺序图
整体架构为
- MyUmlInteraction
- ClassManager
- MyClass自身信息
- AttributeManager
- OperationManager
- AssociationManager
- InteractManager
- MyInteraction
- StateManager
- MyStateMachine
- ClassManager
UML图:
taskThree
taskThree添加了检查的功能,因此为较为复杂的检查方法建立相应的Checker
,将逻辑提取抽离
架构图为:
具体交互图为:
复杂度分析:
四个单元架构设计与OO方法理解的演进
四个单元架构设计
UnitOne
由于第一次作业较为简单,所以当时实现基本上采用面向过程的模式,第二次作业在实现时考虑了拓展性和类的功能独立性,第三次作业已经掌握并实现了继承多态的设计,第四次博客作业时,对第三次作业进行了重构,才算真正理解了面向对象中继承多态的终极奥义
第一单元的代码量相比于其他三个单元而言应该是最多的,由此也更能体现出优秀合理的架构设计对简化代码逻辑,减少代码行数,实现时的调试,后期的拓展性等方面的显著性帮助
个人认为课程组提供的推荐设计应该是一个极佳的设计,在第四次重构时也选择的是这一设计方案(至于在做前三次作业的时候没有选择的原因,应该是当时对指导书中提到的推荐设计并没有充分理解以及当时局限于某些功能的具体实现和性能优化)
具体的架构即为:
如图由于所有类继承自同一个类Item
,所以全程只需要对Item
操作,没有零零碎碎杂七杂八,各个类与不同的需求也一一对应,方便未来需求的拓展,降低了类与类之间的耦合性,增强了系统的可扩展性。
UnitTwo
第二单元的设计较为统一,大致可以概括成输入处理,调度器,电梯三个部分,充分利用缓冲解决不同部分处理请求的速度差异问题,通过适当的调度算法和楼层类的设计对性能进行优化
第二单元主要考察对多线程的理解,线程安全性应该算是基础需求,而一个优秀的架构必然会增强线程安全性,上述提到的三部分的结构个人认为只能算作中规中矩的架构设计,希望未来有机会可以深入研究以得到更好的架构设计
UnitThree
第三单元对个人的设计要求不高(或者说并没有为个人设计留下更多空间,毕竟需要实现的接口都是确定的且功能固定的),主要考察的是对JML的理解,按照JML的约束实现对应的若干接口。在实现过程中,不断将功能独立的算法单元单独提取,独立成类,减小单一类的复杂度,选择实当的容器和算法以合理匹配当前的需求。
UnitFour
第四单元的设计主体为manager
架构,即为不同类型的UML图的查询设置对应的manager
,各司其职,功能单一。在对类的具体实现中,也对查询时不相关的功能实现进行分离,使得查询逻辑简单,函数调用过程清晰,增强了后续的拓展性和可维护性。
对OO方法理解的演进
最开始接触面向对象设计的想法就是“哦,面向对象,那是不是就是管理对象以实现功能,那么面向对象设计这门课程是不是就是教我们如何更加合理高效地管理对象”
一学期的课程下来也确实如此:不同的架构设计、不同的容器选择、不同的设计模式都是为了更加合理高效地管理对象
通过自己的设计赋予这个对象以灵魂:它不能仅仅满足当前的需求,同时应当考量自己对于整体设计的耦合度的贡献,对拓展性的贡献,对可维护性的贡献;它的生命也不应该是随着创建而产生,随着回收而消亡,它应当是贯穿于项目的设计、实现、测试、使用的全过程。只有当项目中的各个对象各司其职,不重复,少耦合,强鲁棒的时候,这一项目才能算是真正完成。
面向对象区别于面向过程正是在于它可以保证最终的代码实现可以完全按照当初的设计,甚至在实现的过程中不断完善,优于最初的设计,它契合项目开发者或软件设计者的思维方式,它会使他们觉得“哦,我按照我的逻辑思维设计,最后的实现也肯定会八九不离十”,它减少了对软件开发者的束缚,可以让软件开发者大胆设计,让软件的各个功能明确划分,让软件的实现成为逻辑的再现。
四个单元测试理解与实践的演进
类似于每单元的三次作业的迭代演化,每单元的评测机也随着任务的需求的增加而不断迭代开发演进,四个单元四个评测机,通过随机性或对拍形式的测试增强系统的鲁棒性。
测试是检查软件功能的最直接的方式,每单元对自己代码的测试必不可少,比如第一单元对表达式的随机生成然后求导对比,第二单元的结果检查,第三、四单元的对拍。
测试同时也具有局限性,比如涉及到线程安全时,如果不具备并发性的测试环境,可能很难发现自己的错误,所以不能完全依赖测试,代码实现阶段要不断地头脑风暴减少错误的发生。
测试也需要具备一些技巧,虽然随机生成的数据省时省力,但可能不会对一些重复数据的情况进行有效性的检查,或者对于一些边界数据的检查的概率较小,所以测试也不能完全依赖于自动,还需要手动构造一些数据,比如第四单元手动画UML以检查一些异常或边界情况,为第三单元某些复杂功能构造特殊的测试样例以检查程序的鲁棒性和性能。
当然,如果没有好的架构作为前提,那么测试会变得异常艰难。
课程收获
如果用四句话总结OO课程的话,我想应当是:
赢的让人赢得痛快,输的让人输得明白,无论输赢都有学到,无论胜负都有赚到。
感谢OO课程组策划的较为完备的评测反馈体系,通过中测、强测、互测、bug修复几个环节让我们能快速地提升面向对象设计能力,通过研讨课补充面向对象设计相关的知识。
四个单元的任务设计的主线是清晰的,不同单元的侧重点可以让我较全面地理解面向对象设计,从继承、多态、多线程到契约式设计、UML的构造与使用,从各式各样的设计模式到检验架构的设计原则,都学有所得,有所收获
希望未来能对Java后端有更加深入的了解,能将所学应用。
改进建议
1.每次实验可否提供参考答案?OO的每次实验任务都很独立,答案公布也不影响16次任务和其他的实验任务,如果说不公开实验中的几次程序设计答案还可以理解,那有些改错或者填空题不公布答案就不是很能理解了,是为了防止下届做实验时抄袭吗?(也不知道每年的实验题是否一样),每次2小时的实验完成后不知道自己对错对自身的提升是很小的(这也不是期末考试考完就算了,有些实验内容的理解明显是对这一单元任务完成是有帮助的哇)
2.虽然能理解课程组让我们掌握契约式设计的苦衷,但形式载体能否不再用JML,老师和助教对JML也有所了解,一个官方都不再维护的产物为什么还要让我们使用呢?(尤其是使用工具链?)
3.个人觉得第四单元三次作业的设计不太合理,可能烤漆减负可以换一种形式,而不是降低作业的难度?比如对一些有歧义的需求直接在指导书里进一步说明一下?
4.建议课程组充分挖掘每单元的优秀设计,比如完善企业号的功能,在每单元结束之后激励同学分享自己的优秀设计,形成推送,如果只有优秀代码展示(而且后续几单元好像连这个也没有?)真的收效极小。
5.寒假先导篇的最后几个任务开放一下互测、bug修复等内容?让同学们提前适应一下,体验一下互测的乐趣(见识一下自己的代码有多烂?)
线上学习OO课程的体会
线上学习对OO课程的影响应该是最小的吧?因为课程组和学生之间的通讯是及时的,所以整体学习过程不受影响。个人认为缺陷可能是采用录播课的形式,老师缺少了互动的感觉,研讨课采用腾讯会议,分享的同学缺少了一种紧张的氛围?
感谢OO课程组不断改革使得OO课程体系更加完善,有幸享受到改革的成果,相信未来的6系学子定能享受到更优质的课程内容。