OO第四单元总结

一. 本单元两次作业的架构设计

  终于在最后一个单元实现了增量式开发。在本单元第一次作业中,我便构建了图数据结构,第二次作业变得比较简单,无需重构,只是增加状态图和顺序图即可,下面分析第二次作业的架构设计。 

       

  1. 顶级类 MyUmlGeneralInteraction 负责将输入归类,形成3个子UmlElement数组,分配给处理类图,状态图和顺序图的3个类;

  2. 建立基础设施类:graph,实现图的通用方法:加边,dfs,计算可达结点,拓扑排序等。对于类图,类和接口都当作图中的结点;

  3. MyUmlClassModelInteraction处理类图,MyUmlCollaborationInteraction处理顺序图,MyUmlStateChartInteraction处理状态图,三者基于graph类;

  4. 状态,迁移个数抽象成图的结点数和边数,后继状态抽象成计算图中某点的可达结点数;

  5. 参与对象,交互消息抽象成图的结点数和边数, incoming消息抽象成图中某个结点的入度;

  6. 有了图结构之后,类图中的函数实现也变得非常简单。比如计算类实现的全部接口实质,先做拓扑排序,再按照逆拓扑序依次计算每个结点实现的接口。这样一来,计算某个类时,其父类,以及其实现的接口实现的接口都已经算出来了,直接列表相加就行。不需要任何的递归。

  7. 建完3个图后,将所有的查询全部计算完毕缓存起来,之后查询只是访问缓存结果。

二. 四个单元中架构设计及OO方法理解的演进  

1. 表达式求导系统

  由于已经有设计和实现编译器的经验,本单元作业我直接写了一个小型编译器。求导过程可看作是一个翻译过程:源语言:原表达式,目标语言:求导后的表达式。比如第三次作业指导书上对于item的要求看起来复杂,但拆成一个个小单元后,很容易就能写出item的文法,之后采用递归下降分析法,一次扫描,同时完成了格式检查和求导的工作。我设计和实现的求导都是形式求导,实质是字符串的拼接。思路和实现都很简单。在实现的过程中,我对于java的内存分配与释放,浅拷贝以及函数参数和返回值的传递等都非常迷惑。通过课下阅读《java编程思想》,我也算较为深入地理解了java语音以及OO的思想和具体实现形式:封装,多态,继承。

  考虑到扩展性和易实现性的均衡,我选择了易实现性,导致我第三次作业直接重构,没有做到增量式开发。

2. 电梯调度系统

  三个线程:电梯,调度器,主线程(输入线程), 采用worker thread,生产者消费者模式。main向request中放入请求,调度器从request中拿出请求并分配给一个电梯(放进该电梯的task处),电梯从自己的task中拿出请求并执行,car是电梯的轿厢,代表电梯内的请求。此种实现方式不是电梯去向调度器要任务,而是调度器主动分配任务给电梯。整个架构耦合度较低。

  在这次编写并发程序的过程中,我不仅学会了注意线程安全性(多个线程互斥访问临界资源),还学会了注意多线程对共享变量的可见性,而后者往往容易被人忽略。《java并发编程实践》这本书对并非编程讲得非常好。

  以前在上操作系统的时候,直接用c去实现简单地并发调度非常困难。而java面向对象的并发编程方式,是如此的优雅与易用,大大降低了并发编程的门槛。

  本次作业涉及多个对象之间的交互,我使用了面向对象的继承和接口。

3. 地铁调度系统

  最初,我对JML充满了好奇,非常敬佩这种契约式思想。但之后慢慢意识到,JML承诺得太多,但最终能够使用的功能却很少,且非常难用。这也是其没有大规模流行起来的原因吧。  

  本次作业的核心是建立自带缓存功能的graph。虽然整体架构已给出,我们只需完成少量代码,但如何将实际需求抽象成图还是花了好长时间去思考。如何缓存,如何降低时间复杂度,如何以空间换时间,如何均匀分配负载都是值得思考的问题。

  这次作业虽然实现了增量式开发,没有重构,在写第三次作业的时候对于第二次作业已有的代码我一行都没动,只是在MyGraph类里加了求连通块个数的Public的函数。这样一来bug少了,但新加的架构和已有的架构看起来很不协调。

4. UML解析系统

  这次作业我学习了UML的建模思想。那么在实际开发中,UML是否可以代替自己手工绘制的架构设计图,是不是大家都只画UML来进行交流,不会使用自己随便画的架构图。这是一个我有疑问的点。

三. 对测试理解与实践的演进

  想要轻松通过强测,一个自己构建的强大的测试机是必不可少的。

1. 表达式求导系统

  使用正则表达式生成测试样例,再辅以精心构造的边界测试点。但没有构建自动化的测试程序,导致测试成本高。
2. 电梯调度系统

  这次构建了自动化的对拍程序,通过电梯运行的特定规则来判断结果的正确性。
3. 地铁调度系统

  手工构建了一些比较特殊的测试样例,并进行了压力测试。
4. UML解析系统

  构建并和同学交换了测试样例,众人拾柴火焰高。实现自动化对拍脚本,将自己的结果与其他人的结果进行对拍实现测试。

四. 课程收获

1. OO的思想

  回过头来看,这学期一共输出了1万行的java代码,还是感觉到不可思议。OO使编写具有规模的程序变得更加容易。每次写完,除过几个简单的bug外,代码几乎很少有bug。与之相反,过程化编程的bug非常得多,在上学期写编译器的过程中,我对过程化编程的大量bug的感受尤其深刻。

  OO是一种看待世界的思维方式,没有了上帝视角,组成系统的每个基本元素管好自己的事情,整个系统将井然有序,能够实现非常复杂的功能。

2. java

  真切地感受到了:学习一门编程语言的最好方式就是在做中学。语法稍微了解一下即可上手,做中学使学习过程更加高效和深刻。

五. 改进建议

  1. 架构设计。虽然经历了这么多次作业,但我觉得自己架构设计的本领还远远不够。建议增加一个专注于架构设计的的单元,没有编码。通过学习大量经典的架构设计案例和亲手设计高效的架构,达到之后看到类似本课程每一次作业难度的架构设计时,能够在短时间快速给出一个高效架构的本领。

  2. 增加讨论区搜索的功能。讨论区帖子特别多,但没有搜索功能,很难定位到自己想找的帖子。

  3. 建议专门在指导书中加一部分对于细节,对规则具体解读的章节,尤其对于之后像第四单元最后一次作业类似的作业。使得需求更加清晰,明确。

 

 

posted @ 2019-06-21 22:10  Yifan_Liu  阅读(...)  评论(...编辑  收藏