面向对象第二单元总结
一、程序分析
1、第五次作业分析
问题分析:
本单元第一次作业电梯数量只有一部,没有容量限制,所有请求可以直达,因此只要保证最基本的逻辑正确和线程安全足以完成此次作业,但由于是第一次作业,需要为以后的扩充需求做准备,因此要在架构设计上下功夫。
要点
-
线程安全,避免死锁
-
设计易为扩充需求的架构
-
提前思考调度算法
第五次作业的类图:

复杂度分析:
| Method | ev(G) | iv(G) | v(G) |
|---|---|---|---|
| Control.Control(Crowds) | 1 | 1 | 1 |
| Control.addElevator(Elevator) | 1 | 1 | 1 |
| Control.addMessage(PersonRequest) | 1 | 1 | 1 |
| Control.getMessage() | 1 | 1 | 1 |
| Control.run() | 4 | 5 | 6 |
| Crowd.addperson(PersonRequest) | 1 | 1 | 1 |
| Crowd.containsid(int) | 1 | 1 | 1 |
| Crowd.getperson(int) | 1 | 1 | 1 |
| Crowd.hasnext() | 1 | 1 | 1 |
| Crowd.initite() | 1 | 1 | 1 |
| Crowd.isempty() | 1 | 1 | 1 |
| Crowd.itremoveperson() | 1 | 1 | 1 |
| Crowd.next() | 1 | 1 | 1 |
| Crowd.removeperson(PersonRequest) | 1 | 1 | 1 |
| Crowds.Crowds(Control,int,int) | 1 | 1 | 1 |
| Crowds.Crowds(int,int) | 1 | 1 | 1 |
| Crowds.addControl(Control) | 1 | 1 | 1 |
| Crowds.addElevator(Elevator) | 1 | 1 | 1 |
| Crowds.addperson(int,PersonRequest) | 2 | 4 | 6 |
| Crowds.containsid(int,int) | 4 | 1 | 5 |
| Crowds.getfloor(int) | 2 | 2 | 4 |
| Crowds.getperson(int,int) | 4 | 1 | 5 |
| Crowds.isNone() | 1 | 1 | 1 |
| Crowds.isempty() | 3 | 2 | 3 |
| Crowds.removeperson(int,PersonRequest) | 3 | 2 | 4 |
| Crowds.setNone(boolean) | 1 | 1 | 1 |
| Elevator.Elevator(int,int,int,Control,Crowds) | 1 | 1 | 1 |
| Elevator.addmessages(PersonRequest) | 1 | 1 | 1 |
| Elevator.arriveFloor(int) | 2 | 1 | 4 |
| Elevator.calculatenowfloor() | 1 | 1 | 10 |
| Elevator.closeDoor(int) | 2 | 1 | 2 |
| Elevator.closeddoorprocess() | 8 | 8 | 12 |
| Elevator.elevatorisstop(int) | 5 | 4 | 8 |
| Elevator.findnewdestination() | 12 | 12 | 24 |
| Elevator.getBottom() | 1 | 1 | 1 |
| Elevator.getTop() | 1 | 1 | 1 |
| Elevator.inpeople() | 1 | 11 | 15 |
| Elevator.isnooneinelevator() | 3 | 2 | 3 |
| Elevator.openDoor(int) | 2 | 1 | 2 |
| Elevator.opendoorprocess() | 1 | 5 | 5 |
| Elevator.outpeople() | 1 | 3 | 3 |
| Elevator.run() | 6 | 10 | 18 |
| Elevator.thelastdestination() | 5 | 4 | 6 |
| Input.Input(Crowds) | 1 | 1 | 1 |
| Input.run() | 3 | 3 | 4 |
| MainClass.main(String[]) | 1 | 1 | 1 |
总结:
在第一次作业时完成了整个单元的架构设计,后续两次作业均未做出大的修改。模拟一个“真实”的楼层,这个楼层是一个请求的容器,对所有电梯均可见,有请求发出便将请求放置在请求出发地,电梯到达该楼层时将该请求放入电梯并从楼层中删去此请求。这样设计后对于电梯来说就没有了“捎带”这个概念,电梯只要往复的上下楼,遇到有人出电梯或进电梯便停下。另外在考虑到后续多电梯的情况设计了“control”类,本意为中央控制器,负责调度所有电梯,因为本次作业中只有一个电梯,所以control几乎没有实质性的工作。由于设计时间花费时间过长且第一次实现多线程,对很多问题理解不够透彻,导致未能按时提交作业。
2、第六次作业分析
问题分析:
本次作业增加了电梯的数目,电梯容量的限制,所以重点在于多部电梯的调度。
要点
-
采用调度策略,尽量优化时间
-
0楼要特判,遇到直接跳过
第六次作业的类图

复杂度分析:
| Method | ev(G) | iv(G) | v(G) |
|---|---|---|---|
| Control.Control(Crowds,int) | 1 | 2 | 2 |
| Control.addMessage(PersonRequest) | 1 | 1 | 1 |
| Control.getElevators() | 1 | 1 | 1 |
| Control.getMessage() | 1 | 1 | 1 |
| Control.run() | 4 | 5 | 7 |
| Control.setElevatornum(int) | 1 | 1 | 1 |
| Control.startElevators() | 1 | 2 | 2 |
| Crowd.addperson(PersonRequest) | 1 | 1 | 1 |
| Crowd.containsid(int) | 1 | 1 | 1 |
| Crowd.getperson(int) | 1 | 1 | 1 |
| Crowd.hasnext() | 1 | 1 | 1 |
| Crowd.initite() | 1 | 1 | 1 |
| Crowd.isempty() | 1 | 1 | 1 |
| Crowd.itremoveperson() | 1 | 1 | 1 |
| Crowd.next() | 1 | 1 | 1 |
| Crowd.removeperson(PersonRequest) | 1 | 1 | 1 |
| Crowds.Crowds(Control,int,int) | 1 | 1 | 1 |
| Crowds.Crowds(int,int) | 1 | 1 | 1 |
| Crowds.addControl(Control) | 1 | 1 | 1 |
| Crowds.addperson(int,PersonRequest) | 2 | 5 | 6 |
| Crowds.containsid(int,int) | 4 | 1 | 5 |
| Crowds.getfloor(int) | 2 | 2 | 4 |
| Crowds.getperson(int,int) | 4 | 1 | 5 |
| Crowds.isNone() | 1 | 1 | 1 |
| Crowds.isempty() | 3 | 2 | 3 |
| Crowds.removeperson(int,PersonRequest) | 3 | 2 | 4 |
| Crowds.setElevators(CopyOnWriteArrayList<Elevator>) | 1 | 1 | 1 |
| Crowds.setNone(boolean) | 1 | 1 | 1 |
| Elevator.Elevator(int,int,int,int,Control,Crowds) | 1 | 1 | 1 |
| Elevator.addmessages(PersonRequest) | 1 | 1 | 1 |
| Elevator.arriveFloor(int) | 2 | 1 | 4 |
| Elevator.calculatenowfloor() | 1 | 1 | 10 |
| Elevator.closeDoor(int) | 2 | 1 | 2 |
| Elevator.closeddoorprocess() | 8 | 8 | 12 |
| Elevator.elevatorisstop(int) | 5 | 4 | 8 |
| Elevator.findnewdestination() | 12 | 12 | 24 |
| Elevator.getBottom() | 1 | 1 | 1 |
| Elevator.getTop() | 1 | 1 | 1 |
| Elevator.inpeople() | 1 | 11 | 15 |
| Elevator.isnooneinelevator() | 3 | 2 | 3 |
| Elevator.openDoor(int) | 2 | 1 | 2 |
| Elevator.opendoorprocess() | 1 | 5 | 5 |
| Elevator.outpeople() | 1 | 3 | 3 |
| Elevator.run() | 6 | 9 | 18 |
| Elevator.thelastdestination() | 5 | 4 | 6 |
| Input.Input(Crowds) | 1 | 1 | 1 |
| Input.getElevatorNum() | 1 | 1 | 1 |
| Input.run() | 3 | 3 | 4 |
| MainClass.main(String[]) | 1 | 3 | 3 |
bug分析:
第六次作业中对wait()和notifyall()方法没有理解全面,导致了互测中一些数据ctle的情况,具体来说就是必须调用获得锁的对象的wait()和notifyall()方法,而不是直接使用wait()和notifyall(),这样子做调用的是当前对象的方法,而当前线程不一定获得当前对象的锁。
总结:
由于第一次作业的问题较多,本此作业的时间大部分用在了修复第一次作业的bug上,调度策略上只采用了最简单的“先到先得”,但同时得益于前一次作业得架构设计,真正在本次作业上花费得时间特别少,只是修改了主类和输入线程中关于电梯数目的读入和电梯线程的创建。本次作业强测成绩为96.45分,说明在此架构上即使使用最简单的调度策略依然有尚可的性能分。
3、第七次作业分析
问题分析:
本次作业的难点是换乘,最直接的思路就是有一个中央调度器,这个调度器可以查看所有电梯的所有信息然后进行调度,但是这存在很多问题,比如这个调度器必须了解其他电梯的所有信息,违反了oop的设计原则,还有即使这样要做出实时调度决策依然很困难,实现起来难度不小。另外的思路是考虑到只有23层,可以使用打表的方式为每种请求(23*22种)设计好路线,实现起来较为简单且经实测性能不弱。
要点:
-
请求的换乘
-
电梯的安全退出
第七次作业的类图:

复杂度分析:
| Method | ev(G) | iv(G) | v(G) |
|---|---|---|---|
| Crowd.addperson(PersonRequest) | 1 | 1 | 1 |
| Crowd.containsid(int) | 1 | 1 | 1 |
| Crowd.getperson(int) | 1 | 1 | 1 |
| Crowd.hasnext() | 1 | 1 | 1 |
| Crowd.initite() | 1 | 1 | 1 |
| Crowd.isempty() | 1 | 1 | 1 |
| Crowd.itremoveperson() | 1 | 1 | 1 |
| Crowd.next() | 1 | 1 | 1 |
| Crowd.removeperson(PersonRequest) | 1 | 1 | 1 |
| Crowds.Crowds(int,int) | 1 | 1 | 1 |
| Crowds.addElevator(Elevator) | 1 | 1 | 1 |
| Crowds.addperson(int,PersonRequest) | 2 | 8 | 9 |
| Crowds.containsid(int) | 1 | 1 | 1 |
| Crowds.containsid(int,int) | 4 | 1 | 5 |
| Crowds.findpeopledestination(PersonRequest,int) | 3 | 5 | 5 |
| Crowds.getfloor(int) | 2 | 2 | 4 |
| Crowds.getpeopledestination(PersonRequest) | 1 | 1 | 1 |
| Crowds.getperson(int,int) | 4 | 1 | 5 |
| Crowds.getpersoninitfloor(PersonRequest) | 1 | 1 | 1 |
| Crowds.isNone() | 1 | 2 | 2 |
| Crowds.isempty() | 3 | 2 | 3 |
| Crowds.removeperson(int,PersonRequest) | 3 | 2 | 4 |
| Crowds.setNone(boolean) | 1 | 1 | 1 |
| Elevator.Elevator(String,Crowds) | 1 | 1 | 1 |
| Elevator.addmessages(PersonRequest) | 1 | 1 | 1 |
| Elevator.arriveFloor(int) | 2 | 1 | 4 |
| Elevator.calculatenowfloor() | 1 | 1 | 10 |
| Elevator.closeDoor(int) | 2 | 1 | 2 |
| Elevator.closeddoorprocess() | 11 | 12 | 17 |
| Elevator.containsfloor(int) | 1 | 1 | 1 |
| Elevator.elevatorisstop(int) | 6 | 5 | 10 |
| Elevator.findnewdestination() | 12 | 16 | 28 |
| Elevator.floorhasperson(int) | 4 | 2 | 4 |
| Elevator.getArriveTime() | 1 | 1 | 1 |
| Elevator.getBottom() | 1 | 1 | 1 |
| Elevator.getCapacity() | 1 | 1 | 1 |
| Elevator.getTop() | 1 | 1 | 1 |
| Elevator.getelevatorId() | 1 | 1 | 1 |
| Elevator.getisend() | 1 | 1 | 1 |
| Elevator.gettype() | 1 | 1 | 1 |
| Elevator.inpeople() | 1 | 10 | 16 |
| Elevator.isnooneinelevator() | 3 | 2 | 3 |
| Elevator.openDoor(int) | 2 | 1 | 2 |
| Elevator.opendoorprocess() | 1 | 5 | 5 |
| Elevator.outpeople() | 1 | 3 | 3 |
| Elevator.run() | 6 | 10 | 18 |
| Elevator.thelastdestination() | 5 | 5 | 7 |
| ElevatorA.ElevatorA(String,Crowds) | 1 | 1 | 1 |
| ElevatorA.containsfloor(int) | 3 | 2 | 3 |
| ElevatorA.getArriveTime() | 1 | 1 | 1 |
| ElevatorA.getCapacity() | 1 | 1 | 1 |
| ElevatorA.getelevatorId() | 1 | 1 | 1 |
| ElevatorA.gettype() | 1 | 1 | 1 |
| ElevatorB.ElevatorB(String,Crowds) | 1 | 1 | 1 |
| ElevatorB.containsfloor(int) | 3 | 2 | 3 |
| ElevatorB.getArriveTime() | 1 | 1 | 1 |
| ElevatorB.getCapacity() | 1 | 1 | 1 |
| ElevatorB.getelevatorId() | 1 | 1 | 1 |
| ElevatorB.gettype() | 1 | 1 | 1 |
| ElevatorC.ElevatorC(String,Crowds) | 1 | 1 | 1 |
| ElevatorC.containsfloor(int) | 3 | 2 | 3 |
| ElevatorC.getArriveTime() | 1 | 1 | 1 |
| ElevatorC.getCapacity() | 1 | 1 | 1 |
| ElevatorC.getelevatorId() | 1 | 1 | 1 |
| ElevatorC.gettype() | 1 | 1 | 1 |
| Input.Input(Crowds) | 1 | 1 | 1 |
| Input.getElevatorNum() | 1 | 1 | 1 |
| Input.run() | 4 | 6 | 10 |
| MainClass.main(String[]) | 1 | 1 | 1 |
总结:
本次作业实现换乘的方式是每种请求设计好路线,有些请求可以直达目的地,有些需要换乘,将所有换乘的中间楼层提前设计好,需要时查询即可。第一次作业中设计了control类本意是调度器,但考虑到实现起来太复杂将此类删除,所以除了输入线程之外其余全是电梯线程。关于abc三类电梯,设计三个子类ElevatorA,ElevatorB,ElevatorC,继承Elevator类并改写部分方法。调度策略依然是先到先得,虽然简单但效果很好,强测得分99.5。

浙公网安备 33010602011771号