BUAA-OO-电梯系列
OO 第二单元作业主题为电梯调度,主要学习目标为熟悉面向对象思想,构造适合的类,管理和操作对象。
第五次作业总结
设计策略
本次作业采用生产者、消费者模式设计,由于只有一个电梯,上锁的目标就针对楼层进行上锁,保证没有同时读写的情况发生。
调度器设计
调度策略主要参考现实中电梯的调度策略,模式都统一为 Random,主要检查当前楼层是否有与电梯运行方向相同的乘客,并且优先载送距离短的乘客,若该请求为空,电梯就转换方向。
UML 图
复杂度
method | CogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
Scheduler.stop() | 1.0 | 1.0 | 2.0 | 2.0 |
Scheduler.setMode(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.Scheduler() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.removePerson(Person) | 3.0 | 1.0 | 1.0 | 4.0 |
Scheduler.move(boolean) | 3.0 | 1.0 | 1.0 | 4.0 |
Scheduler.isEmpty() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getPerson(int) | 4.0 | 1.0 | 4.0 | 4.0 |
Scheduler.getMode() | 3.0 | 1.0 | 3.0 | 3.0 |
Scheduler.getCurUp(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getCurDown(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getCntUp() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getCntDown() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.addPerson(PersonRequest) | 4.0 | 2.0 | 2.0 | 5.0 |
PersonMap.PersonMap() | 1.0 | 1.0 | 2.0 | 2.0 |
PersonMap.personIn(int) | 1.0 | 2.0 | 1.0 | 2.0 |
PersonMap.isEmpty() | 3.0 | 3.0 | 2.0 | 3.0 |
PersonMap.getList(int) | 0.0 | 1.0 | 1.0 | 1.0 |
PersonMap.addPerson(Person) | 0.0 | 1.0 | 1.0 | 1.0 |
Person.Person(PersonRequest) | 0.0 | 1.0 | 1.0 | 1.0 |
Person.isArrive(int) | 1.0 | 2.0 | 1.0 | 2.0 |
Person.in() | 0.0 | 1.0 | 1.0 | 1.0 |
Person.getTo() | 0.0 | 1.0 | 1.0 | 1.0 |
Person.getId() | 0.0 | 1.0 | 1.0 | 1.0 |
Person.getFrom() | 0.0 | 1.0 | 1.0 | 1.0 |
MainClass.main(String[]) | 1.0 | 1.0 | 2.0 | 2.0 |
InputHandler.run() | 4.0 | 3.0 | 3.0 | 4.0 |
InputHandler.InputHandler(Scheduler) | 0.0 | 1.0 | 1.0 | 1.0 |
Floor.isEmpty() | 3.0 | 3.0 | 2.0 | 3.0 |
Floor.getFloor(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Floor.Floor() | 1.0 | 1.0 | 2.0 | 2.0 |
Floor.addPerson(Person) | 0.0 | 1.0 | 1.0 | 1.0 |
Elevator.setMode(String) | 3.0 | 1.0 | 2.0 | 3.0 |
Elevator.run() | 6.0 | 4.0 | 5.0 | 6.0 |
Elevator.personOut() | 4.0 | 1.0 | 4.0 | 4.0 |
Elevator.personIn(Person) | 5.0 | 1.0 | 3.0 | 5.0 |
Elevator.move() | 7.0 | 1.0 | 4.0 | 7.0 |
Elevator.isFull() | 0.0 | 1.0 | 1.0 | 1.0 |
Elevator.Elevator(Scheduler) | 1.0 | 1.0 | 2.0 | 2.0 |
Elevator.doorOpen() | 1.0 | 1.0 | 2.0 | 2.0 |
Elevator.doorClose() | 1.0 | 1.0 | 2.0 | 2.0 |
Elevator.checkPersonTo(PersonMap) | 13.0 | 3.0 | 8.0 | 11.0 |
Elevator.checkPersonOut() | 4.0 | 3.0 | 3.0 | 4.0 |
Elevator.checkDirection() | 20.0 | 1.0 | 2.0 | 8.0 |
Total | 98.0 | 59.0 | 83.0 | 114.0 |
Average | 2.28 | 1.37 | 1.93 | 2.6511627906976742 |
耦合度
class | OCavg | OCmax | WMC |
---|---|---|---|
Elevator | 3.67 | 8 | 44 |
Elevator.Mode | 0 | ||
Elevator.Status | 0 | ||
Floor | 1.75 | 3.0 | 7 |
InputHandler | 2.0 | 3.0 | 4 |
MainClass | 1.0 | 1.0 | 1 |
Person | 1.17 | 2.0 | 7 |
Person.Status | 0 | ||
PersonMap | 1.8 | 3.0 | 9 |
Scheduler | 1.92 | 5.0 | 25 |
Total | 97 | ||
Average | 2.26 | 3.57 | 9.7 |
bug 解析
主要是分配的锁不好,因此一开始写的时候死锁,但修好后公测强测都没出现过 bug。
心得体会
第五次作业初次接触多线程,在概念较模糊的情况下写代码模糊的地方还挺多所以踩了不少坑,但由于作业难度不算太高,因此写的过程中可以比较容易理解多线程的概念。
第六次作业总结
设计策略
设计策略和上次作业相似,采用生产者、消费者模式设计,由于调度算法直接 “继承” 第五次作业的调度算法,因此上锁目标和上次作业基本一模一样。
调度器设计
调度算法和上次作业差不多,这次作业主要是把第五次作业封装后,加入了随机分配方法。思路可以想象成三个不同建筑的电梯,然后把人分配到三个不同建筑去,然后电梯根据分配到的人进行载送。
UML 图
复杂度
method | CogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
Scheduler.stop() | 1.0 | 1.0 | 2.0 | 2.0 |
Scheduler.setMode(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.Scheduler() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.removePerson(Person) | 3.0 | 1.0 | 1.0 | 4.0 |
Scheduler.move(boolean) | 3.0 | 1.0 | 1.0 | 4.0 |
Scheduler.isEmpty() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getPerson(int) | 4.0 | 1.0 | 4.0 | 4.0 |
Scheduler.getMode() | 3.0 | 1.0 | 3.0 | 3.0 |
Scheduler.getCurUp(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getCurDown(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getCntUp() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getCntDown() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.addPerson(PersonRequest) | 4.0 | 2.0 | 2.0 | 5.0 |
PersonMap.PersonMap() | 1.0 | 1.0 | 2.0 | 2.0 |
PersonMap.personIn(int) | 1.0 | 2.0 | 1.0 | 2.0 |
PersonMap.isEmpty() | 3.0 | 3.0 | 2.0 | 3.0 |
PersonMap.getList(int) | 0.0 | 1.0 | 1.0 | 1.0 |
PersonMap.addPerson(Person) | 0.0 | 1.0 | 1.0 | 1.0 |
Person.Person(PersonRequest) | 0.0 | 1.0 | 1.0 | 1.0 |
Person.isArrive(int) | 1.0 | 2.0 | 1.0 | 2.0 |
Person.in() | 0.0 | 1.0 | 1.0 | 1.0 |
Person.getTo() | 0.0 | 1.0 | 1.0 | 1.0 |
Person.getId() | 0.0 | 1.0 | 1.0 | 1.0 |
Person.getFrom() | 0.0 | 1.0 | 1.0 | 1.0 |
MainClass.main(String[]) | 0.0 | 1.0 | 1.0 | 1.0 |
InputThread.run() | 10.0 | 5.0 | 8.0 | 8.0 |
InputThread.InputThread() | 1.0 | 1.0 | 2.0 | 2.0 |
Floor.isEmpty() | 3.0 | 3.0 | 2.0 | 3.0 |
Floor.getFloor(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Floor.Floor() | 1.0 | 1.0 | 2.0 | 2.0 |
Floor.addPerson(Person) | 0.0 | 1.0 | 1.0 | 1.0 |
Elevator.setMode(String) | 3.0 | 1.0 | 2.0 | 3.0 |
Elevator.run() | 6.0 | 4.0 | 5.0 | 6.0 |
Elevator.personOut() | 4.0 | 1.0 | 4.0 | 4.0 |
Elevator.personIn(Person) | 5.0 | 1.0 | 3.0 | 5.0 |
Elevator.move() | 7.0 | 1.0 | 4.0 | 7.0 |
Elevator.isFull() | 0.0 | 1.0 | 1.0 | 1.0 |
Elevator.getId() | 0.0 | 1.0 | 1.0 | 1.0 |
Elevator.Elevator(Scheduler,long) | 1.0 | 1.0 | 2.0 | 2.0 |
Elevator.doorOpen() | 1.0 | 1.0 | 2.0 | 2.0 |
Elevator.doorClose() | 1.0 | 1.0 | 2.0 | 2.0 |
Elevator.checkPersonTo(PersonMap) | 13.0 | 3.0 | 8.0 | 11.0 |
Elevator.checkPersonOut() | 4.0 | 3.0 | 3.0 | 4.0 |
Elevator.checkDirection() | 20.0 | 1.0 | 2.0 | 8.0 |
Total | 104.0 | 62.0 | 89.0 | 119.0 |
Average | 2.36 | 1.41 | 2.02 | 2.70 |
耦合度
class | OCavg | OCmax | WMC |
---|---|---|---|
Elevator | 3.4615384615384617 | 8.0 | 45.0 |
Elevator.Mode | 0.0 | ||
Elevator.Status | 0.0 | ||
Floor | 1.75 | 3.0 | 7.0 |
InputThread | 4.5 | 7.0 | 9.0 |
MainClass | 1.0 | 1.0 | 1.0 |
Person | 1.1666666666666667 | 2.0 | 7.0 |
Person.Status | 0.0 | ||
PersonMap | 1.8 | 3.0 | 9.0 |
Scheduler | 1.9230769230769231 | 5.0 | 25.0 |
Total | 103.0 | ||
Average | 2.340909090909091 | 4.142857142857143 | 10.3 |
心得体会
由于一开始挺纠结共享队列的算法,当时也为了性能想了许多,但到最后代码越写越复杂并且可读性也非常差后,就想到了这个调度算法,不仅能直接继承第五次作业的代码,性能上也不会太差,因此就不继续钻牛角尖,直接使用了
第七次作业总结
设计策略
设计策略和上次作业相似,采用生产者、消费者模式设计,调度算法也是 “继承” 第五次作业的调度算法,因此上锁目标和上次作业基本一模一样。
调度器设计
本次作业和上次作业非常相似,加了楼层限制和改变不同电梯类型的人数限制和运行速度,调度算法和之前作业相似,只改变了分配方法,分配时会验证乘客的目标楼层和起始楼层是否可以给该电梯载送,若不能就跳过该电梯。
UML 图
复杂度
method | CogC | ev(G) | iv(G) | v(G) |
---|---|---|---|---|
Scheduler.stop() | 1.0 | 1.0 | 2.0 | 2.0 |
Scheduler.setMode(String) | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.Scheduler(char) | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.removePerson(Person) | 3.0 | 1.0 | 1.0 | 4.0 |
Scheduler.move(boolean) | 3.0 | 1.0 | 1.0 | 4.0 |
Scheduler.isEmpty() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getTag() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getPerson(int) | 4.0 | 1.0 | 4.0 | 4.0 |
Scheduler.getMode() | 3.0 | 1.0 | 3.0 | 3.0 |
Scheduler.getCurUp(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getCurDown(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getCntUp() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.getCntDown() | 0.0 | 1.0 | 1.0 | 1.0 |
Scheduler.addPerson(PersonRequest) | 4.0 | 2.0 | 2.0 | 5.0 |
PersonMap.PersonMap() | 1.0 | 1.0 | 2.0 | 2.0 |
PersonMap.personIn(int) | 1.0 | 2.0 | 1.0 | 2.0 |
PersonMap.isEmpty() | 3.0 | 3.0 | 2.0 | 3.0 |
PersonMap.getList(int) | 0.0 | 1.0 | 1.0 | 1.0 |
PersonMap.addPerson(Person) | 0.0 | 1.0 | 1.0 | 1.0 |
Person.Person(PersonRequest) | 0.0 | 1.0 | 1.0 | 1.0 |
Person.isArrive(int) | 1.0 | 2.0 | 1.0 | 2.0 |
Person.in() | 0.0 | 1.0 | 1.0 | 1.0 |
Person.getTo() | 0.0 | 1.0 | 1.0 | 1.0 |
Person.getId() | 0.0 | 1.0 | 1.0 | 1.0 |
Person.getFrom() | 0.0 | 1.0 | 1.0 | 1.0 |
MainClass.main(String[]) | 0.0 | 1.0 | 1.0 | 1.0 |
InputThread.run() | 13.0 | 5.0 | 9.0 | 9.0 |
InputThread.InputThread() | 8.0 | 1.0 | 4.0 | 7.0 |
InputThread.checkTag(PersonRequest) | 9.0 | 5.0 | 5.0 | 7.0 |
Floor.isEmpty() | 3.0 | 3.0 | 2.0 | 3.0 |
Floor.getFloor(int) | 0.0 | 1.0 | 1.0 | 1.0 |
Floor.Floor() | 1.0 | 1.0 | 2.0 | 2.0 |
Floor.addPerson(Person) | 0.0 | 1.0 | 1.0 | 1.0 |
Elevator.setMode(String) | 3.0 | 1.0 | 2.0 | 3.0 |
Elevator.run() | 6.0 | 4.0 | 5.0 | 6.0 |
Elevator.personOut() | 4.0 | 1.0 | 4.0 | 4.0 |
Elevator.personIn(Person) | 5.0 | 1.0 | 3.0 | 5.0 |
Elevator.move() | 7.0 | 1.0 | 4.0 | 7.0 |
Elevator.isFull() | 0.0 | 1.0 | 1.0 | 1.0 |
Elevator.getTag() | 0.0 | 1.0 | 1.0 | 1.0 |
Elevator.getId() | 0.0 | 1.0 | 1.0 | 1.0 |
Elevator.Elevator(Scheduler,long,char) | 7.0 | 1.0 | 2.0 | 6.0 |
Elevator.doorOpen() | 1.0 | 1.0 | 2.0 | 2.0 |
Elevator.doorClose() | 1.0 | 1.0 | 2.0 | 2.0 |
Elevator.checkPersonTo(PersonMap) | 13.0 | 3.0 | 8.0 | 11.0 |
Elevator.checkPersonOut() | 4.0 | 3.0 | 3.0 | 4.0 |
Elevator.checkDirection() | 20.0 | 1.0 | 2.0 | 8.0 |
Total | 129.0 | 69.0 | 99.0 | 138.0 |
Average | 2.74 | 1.47 | 2.11 | 2.94 |
耦合度
class | OCavg | OCmax | WMC |
---|---|---|---|
Elevator | 3.5714285714285716 | 8.0 | 50.0 |
Elevator.Mode | 0.0 | ||
Elevator.Status | 0.0 | ||
Floor | 1.75 | 3.0 | 7.0 |
InputThread | 5.666666666666667 | 8.0 | 17.0 |
MainClass | 1.0 | 1.0 | 1.0 |
Person | 1.1666666666666667 | 2.0 | 7.0 |
Person.Status | 0.0 | ||
PersonMap | 1.8 | 3.0 | 9.0 |
Scheduler | 1.8571428571428572 | 5.0 | 26.0 |
Total | 117.0 | ||
Average | 2.4893617021276597 | 4.285714285714286 | 11.7 |
心得体会