第一次作业
1.设计策略
本次作业需要实现一部简单电梯的运行,很自然的,我选择将本次作业的三个部分,读入数据、调度数据、电梯运行作为三个线程来运行。其中读入数据的线程比较简单,根据提供的接口使用方法顺序读入即可。调度数据我实现了一个调度器类,用于管理两个队列,一个是读入数据的队列,一个是给电梯分配任务的队列。电梯作为一个类,实现了运行,进出人等功能。
2.可拓展性
我认为本次作业的可拓展性做的比较不错,增加电梯只需要再创建一个线程即可,增加功能也只需要在电梯内部进行增加。
3.程序结构分析
UML类图如下:
协作图如下:
度量分析如下:
除了电梯的run方法外其他方法复杂度都控制的比较好,因为电梯需要考虑优先去接哪一个楼层的人,所以run方法的复杂度比较高。从类图也可以看到电梯类的复杂程度是最高的。
4.bug分析
本次作业我在强测和互测中均没有被发现bug。在互测中我也没有发现其他同学的bug。
第二次作业
1.设计策略
本次作业要求实现多个电梯并拓展了可以到达的楼层。我在第一次作业的基础上新增了一个整体队列用于给每一个电梯提供自身独享的队列。由于出现了负楼层,新增了根据楼层转化队列下标的方法。
2.可拓展性
可拓展性比较好,新增功能只需要在相应类中增加方法或者增加类即可。
3.程序结构分析
UML类图如下:
协作图如下:
度量分析如下:
可以看到第二次作业的分析整体来看与第一次作业区别不大,电梯的run方法由于设计原因复杂度还是比较高。
4.bug分析
本次作业我在强测和互测中均没有被发现bug。在互测中我也没有发现其他同学的bug。
第三次作业
1.设计策略
本次作业新增了电梯的种类以及换乘和动态增加电梯的功能。对于电梯种类,我给电梯定义了一个floor数组用于标记可以到达哪些楼层,并用String来保存电梯的类型和名字。对于换乘,我采用了写回请求队列的方法。首先调度器在调度时如果发现一个无法直接到达的请求,就对此对象进行一个特殊的标记。电梯在接到有特殊标记的Person时会将其送到最近的换乘楼层(1或15层)并将此请求写回请求队列。对于动态增加电梯只需要在读入线程创建电梯即可。
2.可拓展性
本次作业我觉得可拓展性还是比较不错的,由于电梯、调度器、读入器分离,实现了比较好的拓展性。
3.程序结构分析
UML类图如下:
协作图如下:
度量分析如下:
本次作业的复杂度比上次作业稍有上升,但总体来说还算比较正常。
4.bug分析
本次作业我在强测与互测中均没有被发现bug。在互测中我发现一些同学在运送大量换乘人员时会超时,还有一些同学对于某种特殊的需求无法到达。
心得与体会
在第二单元的学习中,我深刻认识到了线程安全的重要性,我身边同学几乎百分之八十的错误都来源于线程不安全所导致的死锁或者数据冒险,而且线程安全的问题很有可能自己测试时很难发现,一些错误可能只有非常小的概率发生。还有设计原则也必须要清晰,应该谁做的工作就应该谁做,不应该让某个线程做不属于它的工作,这样不但提高了耦合度,还有可能引发意想不到的错误。我们应当在一开始就规划好整个程序的大体框架,不能写到哪里算哪里。