OO第二单元总结
前言
随着OO第二单元落下帷幕,神奇的电梯调度终于告一段落。相比多项式求导章节,电梯调度问题实现了单线程向多线程的延伸,面向对象编程的优势也逐渐显现。
第五次作业
第五次作业的内容是设计单部多线程傻瓜调度(FAFS)电梯,这次作业还是非常简单的(不需要考虑捎带)。根据分工不同,我一共新建了三个类:Main类读取INput的输入并存入队列中;CommandInput类保存请求信息,并根据请求调度电梯;ElecRun类即为电梯行为的模拟,根据调度器的要求控制电梯运行。由于只有三个线程工作(主线程、输入线程和电梯线程),请求冲突的情况非常简单,只需维护请求队列即可。
·类图
·耦合度图
·时序图
·设计原则检查
S:功能抽象程度不足,部分类(如ElecRun类)所承担的功能过多,导致耦合度高;
O:功能定义较完善,适合扩展;
L:未出现子父类,LSP原则无从体现;
I:未使用接口,无法体现ISP原则;
D:无分层模块,无法体现DSP原则。
·关于互测
分析第一单元的互测后,可以发现绝大部分的“刀人”来自于卡输入数据的WA。而第二单元作业的一大特点即为已提供输入输出接口,因此之前惯用的“刀人手法”并不适用。我所在的房间并未出现成功刀人的例子,所以实在没什么好说的。。
第六次作业
第六次作业的内容是设计单部多线程可捎带调度(ALS)电梯,捎带调度的要求让本次作业多了不少设计方向。这次我使用的是ALS调度,架构方面沿袭第五次作业。这次作业与第五次作业最大的区别就在于捎带策略的不同,如果不采用捎带,一次只执行一个请求命令的话,那么时间上肯定来不及。我设计的电梯线程的主要运行逻辑是:在电梯内为空时,将队列中的第一个请求作为主请求加入电梯内部请求队列;在电梯运行过程中,对于所经过的每一个楼层,电梯都向调度器发送请求,遍历请求队列,选取出发楼层为当前楼层且目的楼层方向与电梯运行方向相同的请求加入电梯内部队列。由于只有一部电梯在运行,所以只需维护输入线程与电梯线程访问调度队列时的冲突即可。
·类图
·耦合图
·时序图
·设计原则检查
S:功能抽象程度不足,分类较少,部分类(如ElecRun类)所承担的功能过多,导致耦合度高;
O:功能定义较完善,适合扩展;
L:未出现子父类,LSP原则无从体现;
I:未使用接口,无法体现ISP原则;
D:无分层模块,无法体现DSP原则。
·关于互测
这次作业强测挂了,没进互测。。这里我谈一谈强测挂了的原因,也给各位提供教训。
按照ALS调度规则,当电梯内有请求时,选取新请求的条件为起始楼层在当前楼层且运行方向与电梯当前运行方向相同。然而,由于当电梯到达当前楼层时,电梯内乘客自然也有可能离开电梯。当电梯内乘客一次性走完时问题就出现了:此时电梯还有运行方向吗?而我确定电梯运行方向的依据是电梯主请求的运行方向,假如电梯在同一楼层出现全体乘客离开电梯且有新乘客进入电梯的情况时,我的电梯模拟程序就会因访问空队列而报错。这一点我当时已经想到了,但是在发现bug时并没有立即修正,导致我之后继续编写时漏了这个bug,最终导致了没进互测的结局。所以说,发现bug一定要及时解决,即便有事耽搁也至少要留下注释提醒自己。
第七次作业
第七次作业的内容是多部多线程智能(SS)调度电梯,主要难点在于多部电梯间的竞争协作。为了避免多部电梯同时访问请求队列而出现重复进人的情况,我将访问请求用一个进程控制块保护,同时只能有一部电梯访问请求队列,其它电梯线程将进入等待队列。另一难点即为请求分割,例如一位乘客需先乘A电梯,后乘B电梯,如何保证进入电梯的次序不混乱也很重要。我将请求分割后保存在队列中,每个请求对象都保存了其后继地址,这就保证了访问次序的控制。这次作业的主要优化方向是请求分割的优化,这部分我偷懒了,基本没做什么优化,也没什么经验可以介绍了。。
·类图
·耦合图
·时序图
·设计原则检查
S:功能抽象程度不足,部分类(如ElecRun类)所承担的功能过多,导致耦合度高;
O:功能定义较完善,适合扩展;
L:未出现子父类,LSP原则无从体现;
I:未使用接口,无法体现ISP原则;
D:无分层模块,无法体现DSP原则。
·关于互测
这次互测我所在的房间非常佛系,没有出现成功刀中的情况。。所以互测方面我也没什么好说的(捂脸)。
心得体会
规范化编程,合理分配对象任务能够使代码复用性提高,免得每次作业都得重构代码。
开始编程之前先理清编程思路,将任务模块化,分配到不同对象中。每个对象的功能明确,尽量避免身兼数职的情况发生(不然checkstyle没过再改也麻烦不是)。
弱测真的很弱。。即便过了弱测,也还需要自己检查编程思路,自己造数据进行测试,测着测着bug就出现了(误)。