OO第二单元总结
一、设计策略
对于前两次的电梯,由于电梯的种类单一,我采取的设计是采用的最简单的生产者-消费者模式。即输入线程作为生产者,将新的请求信息传递到调度室中进行处理,调度室再给电梯线程下达命令。在第三次的作业中由于电梯种类的增加,我又增加了一个控制室,用来控制三种调度室,而每一种调度室负责给一种类型的电梯下达命令,其余的部分和前两次的相仿。
在多线程的协同方面,调度室接受到输入线程的请求之后会将请求存入调度室中的一个ArrayList之中,然后在电梯开关门,以及上下行的过程中将这些请求合理的分配给不同的电梯。这里的合理是指,电梯能去到请求所在的楼层,电梯没有满载,以及这是可行的将请求完成或者完成一部分的电梯。同时当输入线程结束的时候也会将信号传递给调度室,在前两次作业中调度室会将这一消息传递给电梯,当一部电梯得知输入线程结束时,同时将自己的请求全部完成时则会结束。而第三次作业中,由于需要电梯换乘的缘故,因此调度室不会再将这一消息传递给电梯线程,所有电梯线程在得知所有的请求处理完成后才会停止。
二、可扩展性
单一责任原则
第三次作业中,我一共有五个类。
主类,负责初始化和启动其他线程。
输入线程,负责接收请求。
电梯线程,实现电梯的各个功能,包括开关门,上下行,以及按照指定的策略将请求完成。
Control类,负责控制同步输入线程接收的请求,并且进行决策将请求发往各调度室。
调度室类,管理某一种类的电梯,在接收到控制类的请求之后,将请求分配给最优的能完成请求的电梯。
开放封闭原则
对扩展的开放程度还行,电梯功能的扩展可以在电梯类里扩展,电梯的种类可以在调度室里扩展,请求的功能增加可以在控制类中进行扩展,且不会影响之前的调度于各线程的运行。对修改的封闭性有待完善,主要是主类中的初始化,对于每一种初始情况都需要进行一定的修改。
里氏替换原则
由于我只有输入类和电梯类关于线程类的继承,因此当然是满足里氏替换原则的。
接口隔离原则
因为没有用到任何接口,因此不考虑这一原则。
依赖倒置原则
输入类与控制类平行,调度室类依赖于控制类,电梯类依赖于调度室类,底层只会接收上层命令,并传递命令给底层。因此满足依赖倒置原则。
三、基于度量的程序分析
第一次作业

图1 第一次作业UML图

图2 第一次作业复杂度分析
第一次作业中调度室的复杂度略高,是因为第一次的时候让调度室承担了实现电梯功能的责任。这个在第二次作业中得到改正。
第二次作业

图3 第二次作业UML图

图4 第二次作业复杂度分析
第二次作业中,由于电梯需要实现开门,关门,上下行,进人,出人,判断满载,判断是否为空,到达,以及将信息反馈给调度室等功能,所以权重偏高。然后由于输入线程和电梯线程一直是由一个while循环在不断进行的,而主类是启动这些线程的类,因此循环偏高。
第三次作业

图5 第三次作业UML图

图6 第三次作业复杂度分析
第三次作业首先是调度室的权重以及循环复杂度都很高,是因为调度室里要实现调度,因此我实现了很多方法。至于为什么调度室和输入为什么循环复杂度这么高,我也不是很懂。
四、自己程序的BUG
由于我采用最保守的写法,以及最直接的调度方式,因此只存在性能上的问题,目前还未找到正确性上的问题。
五、分析别人BUG的策略
并没有hack成功别人,我的策略是思考极端情况,尽量使别人产生RTLE。
六、心得体会
多线程单元主要让我学习到一些关于强制在线的处理办法。从自己的结果和其他同学的结果来看,依然使用许多离线的办法,如打出最短路径表等可能效果并不太好,相反直接让所有电梯去抢乘客的方法得到青睐。
其次,本次的设计模式让人非常舒服,基本上这要在上一次作业基础上进行扩展以及重新初始化即可得到下一次的作业,重构的部分非常少。因此需要多学习一些设计模式,这样在做迭代作业时,才会轻松。
最后,多线程的自动化测试相比于写出电梯难度更大,因此要加强相关方面的学习。

浙公网安备 33010602011771号