OO第二单元总结

OO第二单元总结

一.第一次作业

设计策略

第一次作业要实现一个傻瓜电梯,采用先来先服务的算法。首先设计一个输入类作为输入线程获取输入,然后将获得的请求存入容器类,最后创建电梯类不断从容器中获取请求并执行。这样设计需要考虑容器类的线程安全问题,电梯线程在没有请求时要处于wait状态,容器中有请求则立即执行,因此可容器的add()方法中加入notify(),在get()方法中加入wait()。

类图分析

通过类体图可以看出程序核心在Misson类,既要管理请求又要执行notify和wait控制电梯线程,方法中复杂度高的是run()方法,这是由于对多线程不熟悉,没有考虑对电梯操作进行封装来简化run()方法。

bug分析

第一次作业比较简单,没有什么坑点,只要能正确执行多线程通过强测基本不会有什么bug,因此这次没有被找出bug也没找到bug。多线程找bug要在不同时间进行输入,这对手残玩家很不友好。

二.第二次作业

设计策略

第二次是设计一个可稍带电梯,即改进第一次的先来先服务算法。这一次相比上次只需改进算法,难度不大,但我做的不好。这一次在上次的基础上新增了Controller和CurrentReq两个类,Controller用于调度,CurrentReq存放可稍带的请求,Mission类存放主请求,电梯每运行到某层就遍历可稍带请求队列让人进出,主请求结束后让最早的可稍带请求成为主请求,若CurrentReq为空则取Mission请求作为主请求。Controller决定将输入送入Mission还是CurrentReq。

这样设计其实有很多问题,比如代码重复率很高,设计两个容器类管理不便,易出bug,且可扩展性不强,Controller的存在不是很有必要。

类图分析

与上次作业相同run()方法复杂度高,因为抽象层次还不够高,且Controller,Mission,CurrentReq都有add和get方法,是很不好的设计,共享资源有两个类更难保证线程安全。

bug分析

这次被找出两个bug,一个是更换主请求时出发楼层设为了可稍带请求的出发楼层,应为当前楼层,第二个是设计层的bug,即直接将输入存进CurrentReq中,若此时电梯已关门则不能进行in操作,这样会造成人没有进入电梯但到了到达楼层却会出电梯的错误。这些bug的出现就在于设计的太复杂,导致很多细节方面难以考虑全面,因此我在第三次作业重构了第二次的ALS,使第三次的设计简化了很多。

由于写的太烂被分在C组,找bug容易了很多。。。这次我构造了一些易错的样例,比如更换电梯运行方向同时更换主请求,卡时间在关门后输入当前楼层的请求,于是找到了一些程序会出现请求缺失和死锁的情况。

三.第三次作业

这次作业有三部各不相同限制很多的电梯,单部电梯的运行只需在第二次的基础上加上限制即可,难点在于要设计控制类进行调度,分配请求给相应电梯,还要处理一部电梯到不了的请求。

首先重构了第二次的ALS,将可稍带队列放入Elevator类中,而不是单独设类,电梯设queue队列存放被分得的请求,每取一个作为主请求就遍历queue取请求翻入可稍带队列,每到一层就更新可稍带队列,然后据此进行in和out操作。这次作业更像是继承了第一次的设计,也只设计了三个类,输入,控制,电梯,控制器要根据可停靠楼层调度请求给不同电梯的queue,需要三个数组和三个queue构造,电梯类需要各自限制条件和contrller来构造。请求输入后进行controller.add(),分配给不同的queue,若一部电梯不可达则拆成from->1,1->to,将第一个重新调度,第二个存入Controller的mission的队列等待第一个请求完成再重新调度,电梯类也有一个和Controller一样的mission队列,每到1楼若有人出则根据此人id判断是否再mission中,存在则取出进行add。每个电梯最终停下要进行setWaitting通知controller,再getWaitting得知另外两部电梯是否停下,都停下则结束程序。

类图

这次run方法抽象层次很高,复杂度明显比前两次要低,而且方法数量减少,Total也减少,实现的功能却更多,由此可见良好的设计架构对程序帮助很大,不仅写代码时思路清晰速度快,实现的程序也有较好性能。

缺点应该就是三次作业都没有优化,将需要换乘的请求全送到1楼能保证正确性但无疑有时效率极低,这也导致这次作业几乎没得到性能分。

bug分析

这次作业测试了一些需要很多换乘并更换请求的样例,不过没找到bug。

四.心得体会

通过电梯作业我了解了多线程的运行机制,知道如何使用synchronized锁来对共享资源上锁保证线程安全,达到互斥效果。另外第二次作业复杂杂乱的设计和第三次作业的重构使我对架构设计的重要性有了更深刻的印象,好的架构能帮助我们节省时间,提升性能,不好的架构就要不断修修补补,使程序显得冗余,细节处易出bug。对方法的抽象提取也很重要,这样能减少复杂度,更重要的是易于维护。

整个电梯作业给了我一种提升的感觉,第一次作业对多线程了解很少,难以上手,各种尝试之后完成了作业却不知甚解,于是第二次作业就出现各种各样的问题,经过深入学习后第三次作业就能很好的完成。OO的学习也是如此,仅仅勉强完成作业远远不够,只有明晰什么东西需要抽象成类和对象,如何做到高内聚低耦合的设计,才能写出一个不错的OO程序。

posted on 2019-04-23 20:57  ture117  阅读(112)  评论(0)    收藏  举报

导航