OO第四单元博客:UML

1 正向建模与开发

        正向建模与开发是指从高层次的抽象模型逐步转化为具体的实现。在本单元中,我大致经历了以下的步骤,实现代码的编写:

  • 需求分析:仔细阅读指导书,大致记录图书馆和图书馆下的预约处、借还处、漂流处等不同的需求,并从用户角度分析借书、还书、预约等流程。

  • 系统设计:根据需求,设计大致的架构与模块,运用UML创建图书馆系统的静态模型,主要是使用类图,分析不同类之间的关系以及一些可能会用到的函数。根据用户借书、还书、预约等流程,画出对应的状态图与时序图。但是,在具体的实践中,我有必要反思:由于刚开始接触UML模型,并且不熟悉图的画法,最开始的类图、状态图、时序图是在草稿纸上生成的,具体的图的实现都是在代码编写后进行的。

  • 代码编写:根据以上的设计进行代码的编写,实现图书馆系统的各个功能模块。

  • 测试与验证:对于一些细节,自行构造一些数据,还有就是通过同学的测评机来debug。

2 本单元作业的架构设计

2.1 第十三次作业

Main类

        图书馆采用单例模式,在Main中创建,所以Main类和Library类之间也是关联关系。

Library类

        图书馆类统一管理借还处、预约处的图书,用户在图书馆类中完成借书、还书、预约、取书等操作。作为主管机构,图书馆类与其下设的预约处(OrderOffice类)和借还处(BorrowAndRreturnOffice类)都是关联关系。因为图书馆中还记录了用户名单,所以图书馆类与Student类也有关联关系。

OrderOffice类

        预约处类,为了记录书号、预约者、日期等信息,重新创建了一个OrderedBook类,在OrderOffice中有一个OrderedBookArrayList,所以,OrderOfficeOrderedBook之间也有关联关系。

2.2 第十四次作业

DriftOffice类

        本次作业新增漂流角类,归于图书馆类管理,用户的捐赠、借还非正式图书、非正式图书的升级都在图书馆内进行,在Library中有一个DriftOffice类的实例化,所以Library类和DriftOffice类之间也是关联关系。

2.3第十五次作业

        架构与第十四次作业一致,增添了用户信用积分机制,用户的信用积分管理也是在图书馆内随着借阅、还书、预约、取书、整理、漂流等流程进行。

3 四个单元中架构设计思维的演进

3.1 第一单元

        第一单元是多项式表达式化简。当时对面向对象的了解只停留在先导课上,初次独立实现一个完整的面向对象的程序时,确实让我犯了难。

第一单元中:

  • PreProcess类:预处理阶段

  • Token类,Lexer类与Parser类:递归下降与表达式解析

  • Factor类,Term类和Expr类:数据结构

        当时我自己本身对于面向对象的设计还不太清晰,以上的类都是根据公众号的递归下降讲解以及实验代码构造的,对于与计算相关的Mono类和Poly类,是参考学长学姐的实现方式而构造出来的,可见初期的我在架构设计方面还比较薄弱。

        通过第一单元的作业,我初步了解了面向对象的形式,也在完成作业的过程中体会到了面向对象中实现,继承和多态的特性,对于这些特性的运用,初步感受到了面向对象的便利。同时,本单元最重要的一个特征就是实现层次化设计,不论是表达式递归下降的层层解析,还是计算中层层嵌套,都能体现层次化的思想。

3.2 第二单元

        第二单元模拟电梯运行。第一次接触多线程编程,面对第五次作业有点无从下手,实验中以及课堂上老师讲解的的“生产者-消费者”架构为我提供了思路。在实验架构的基础上,我增添了调度策略算法、电梯运行策略分析,实现一定的层次化设计。

        同时,为了实现调度器的统一化,我还采用了单例模式,在全局中只实例化一个调度器对象,使调度器能够更好地统筹全局,同时,在调度器中新建双轿厢电梯,使用单例模式有利于DCReset的实现。

        但是,其实在最最最开始的时候,我没有形成完整的流程和功能模块的分析,导致最初的代码写得磕磕绊绊。在面对多线程编程时,要首先根据需要实现的功能,分成多个不同的功能模块,利用前驱图,调度关系,梳理各个线程之间的同步与互斥关系,避免死锁、无人唤醒等异常情况。并规定好不同模块之间的接口,利用共享对象传递信息,然后再自上而下依次实现。

3.3 第三单元

        第三单元是JML规格化设计,本次作业与图论的知识关系较大,要完成的是对人际图的构建与分析,本单元的架构基本由官方包搭建好了,需要我们正确理解JML描述。

        还有需要考虑一些算法、性能层面的问题,本次作业需要查询两个人之间是否连通,所以单独建立并查集类,封装数据容器并统一管理。

        本次作业让我开始有了架构优先的认识,对于一个工程,首先需要有明确的需求,实现规格化设计,考虑每一部分的功能以及可扩展性,而忽略使用的数据结构和具体的方法。最后,依据设计填充代码,在这个过程中,我们还需要考虑有利的数据结构,以及性能、算法的优化。

3.4 第四单元

        第四单元是学习UML统一建模语言,本次作业强调正向建模与开发,利用UML创建系统的静态和动态模型,包括用类图、状态图、时序图。代码架构的整体设计也是在这一步完成,在简单绘制类图时,先根据不同模块(比如图书馆、用户、借还处等)单独建类,再合理组织每一个模块之间的关联、继承等关系,实现图书馆总管理,将各个功能分配到不同的类中完成,架构也比较直观。

        同时,根据流程,需要提前绘制状态图、时序图,才不至于代码编写时没有一个整体的框架,但是由于我刚开始接触UML,所以这个步骤是在草稿纸上实现的。

4 四个单元中测试思维的演进

        在第一、二单元中,过于依赖测评机,自以为跑了很多次测评机没有出现问题就是完全正确了,没有对代码进行更加精细的检查,导致第三次作业挂了。但是,反过来思考,测评机采用的是随机测试,而在测试中覆盖率才是最重要的影响因素,对于极端数据几乎难以进行有效覆盖,所以不能太依赖测评机。

        第三单元中,Junit测试为我们覆盖测试提供思路,当JUnit测试检验代码实现与规格的一致性,即可验证代码功能的正确性,同时有利于检查边界条件、发现与修复问题。当需要对代码进行重构或修改时,JUnit测试可以作为安全网,确保修改后的代码仍然符合规格要求。通过运行测试用例,可以验证修改是否影响了代码的功能和行为,从而保证系统的稳定性和可靠性。

        但是由于在作业中,为每一个方法构造JUnit测试是不现实的,所以,在所有的作业中,以测评机为主,用python进行测试数据生成和对拍。对于边界条件,需要自行构造一些样例。

5 课程收获

        虽然是一段痛苦的旅程,但是通过面向对象的这门课程,我不仅学会了一门编程语言,更多的是体会到面向对象的编程思想,同时还接触与了解了JML规格和UML统一建模语言,收获颇丰。

        在课程学习的过程中,我从过去的面向过程的编程思想逐步过渡到面向对象的编程思想,在我看来,尽管这二者有显著的不同,但其实他们之间并非割裂,在面向对象模块内部方法主要还是依靠面向过程的实现。

        另一个方面,在架构的设计与构造中,课程让我明白合理的模块和层次设计不仅可以满足良好的可扩展性,另一方面其实也可以简化代码的工程量。在第一单元和第二单元的作业中,架构设计的重要性不言而喻,一个好的架构具有可扩展性,在每次作业的迭代中会相应地减少一点工作量。

        虽然学习的过程艰难,并由于自己粗心的毛病,在两次作业中获得很不理想的成绩,但是还是很感谢OO这门课能让我熟悉架构设计,熟悉规格方法以及UML统一建模,让我看到自己在一点点进步,心理素质也一点点提高。

        最后,感谢OO课程组的老师、助教学长学姐们,感谢我的好朋友们,感谢他们的每一次帮助和支持,我倍感温暖与感激。

        “追风赶月莫停留”,来日之路光明灿烂,继续加油吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值