[OO] Unit2 Summary 电梯系列
其他
2020-05-15 10:20:39
阅读次数: 0
[OO] Unit2 Summary 电梯系列
架构相关
UML类图
请求处理流程
多线程协同与同步控制
时间线流程图
- 我在这上次作业的多线程控制中,采用了由父线程创建子线程的方式
- 考虑到整个程序的结束是由InputThread发出的,所以将InputThread作为Main创建的唯一线程,并且由InputThread再创建子线程
- 具体的线程管理方式可由流程图看出
同步控制
- 大多数采用synchronized关键字进行同步与保护
- 少数使用现成的线程安全容器如ConcurrentHashMap与BlockingQueue等
- 关于线程终止的问题,我采用了父线程判断什么时候应当结束子线程,并通过interrupt尝试停止子线程,最终使用join函数等待子线程都结束后再终止
第三次作业架构设计
可扩展性分析
- 经过第一单元的磨练,我在第二单元中尽可能地考虑了优化时的可扩展性,架构与性能的平衡
- 一个好的设计,一定是优化能够方便地建立在架构上,并且这样地优化策略能够很好地扩展
- 具体的优化策略可以由我之前在研讨课上地分享看到
- [OO] 第二单元 电梯优化策略
- 可以看到,对于可扩展性,只需要改变估价函数即可,估价函数的定义见上述博文
设计原则分析
原则 |
分析 |
单一责任原则 |
经过多次小范围重构,个人认为我在分类与分包的颗粒度上做得很好 |
开放封闭原则 |
这一点做得较好,但在更改估价函数时,需要对原有代码进行更改与封装性破坏,似乎这不可避免 |
里氏替换原则 |
此次作业不适用,未使用继承语法 |
依赖倒置原则 |
总体来讲,这一点还好 |
接口分离原则 |
本次作业未使用接口,并且不同类之间差异较大,不需要使用接口进行抽象 |
基于度量分析
- 由于更新IDEA后MetricsReloaded插件无法使用,故使用DesignitiveJava进行一些简要分析
- 由上图LCOM(内聚缺乏度)可以看出,我的设计整体来说比较符合高内聚低耦合的特点,唯一需要增加内聚的是参数控制Config类,它既包含了全局的参数信息,又包含了每个电梯的特异性参数信息,应当将这两种参数分开作为两个类
- 由FANIN(越大越好)与FANOUT(越小越好)指标可以看出,设计控制的部分类FANOUT较高,如Controller与DistributorThread
- 可能的原因是这两个类承担了较多的分配与控制任务,需要掌握的信息也比较多,因此引用其他类的次数也就较多
- 架构与流程图和协作图见上
BUG分析
自己的bug分析
- 电梯系列作业中,一共出现了2个BUG,都属于线程安全的问题
- 两个BUG具有相似之处,即某线程还未进入可相应Interrupt的状态,却受到了Interrupt,导致下一次到达某个该Sleep的地方提前中断Sleep,最终导致相邻两个时间太短而WA
- 但神奇之处在于本地测试时很多次才会爆出一个Bug,我在本地复现这个bug的时候遇到了极其难以复现的问题
- 即使最终能够复现,同一个测试样例也会在不同的时候WA,不可预估
- 最开始以为是课程组评测机有问题,最终发现还是自己太年轻
- 所以如果这篇博客有幸能被学弟学妹们看到,请一定记住如果本地无法复现BUG,一定是有线程安全的问题,且需要关注极小的运行速度差别导致的问题
Hack策略
心得体会
线程安全方面
- 在这一单元中,最难过的坎就是线程安全的问题,并且其难以复现性将debug的难度大大提升
- 遇到这样的线程安全问题,不能盲目地急躁地debug,而是仔细地从代码逻辑上形式化找线程安全的问题,需要充分考虑各种代码执行情况
设计原则方面
- 关于设计原则,我最大的感受就是应当尽力遵从,如果某个地方不符合某个设计原则,不一定会出错,但是这里应当极大地仔细谨慎
- 总的来说,设计原则在这一单元地作业中主要体现在代码质量上以及可维护性和可扩展性上,绝大部分遵从设计原则写出来地代码对作者和阅读者都十分友好,这无疑是极具幸福感的事情
碎碎念
- 总体来说,第二单元相对于第一单元来说,更有趣和面向对象,电梯作为OO课程的王牌果然名不虚传…
- 相比于计算机组成课设、OS课设、编译原理课设等我个人认为较
死板机械 的课程,OO课程在一定代码量的基础上,更多的是设计与创新这个灵魂,考验的是玩家怎么玩的嗨,而不是CO、OS、编译等经常需要在一个毫无意义的bug上吊死一天,虽然OO有的bug也能吊死一天 ,但这样的bug往往是设计上的缺陷,个人认为这种才是高级Bug,debug的时候可以很兴奋
转载自blog.csdn.net/ourfutr2330/article/details/105569563