面向对象第二单元总结

面向对象第二单元总结

设计策略分析

本单元的电梯三次作业笔者均采用了相同的结构,类似生产者消费者模式,共有三个主类分别为Request,CubbyHole,Elevator分别代表生产者,托盘和消费者。线程主要为Request线程和Elevator线程,CubbyHole则是共享资源,其中的大多是方法被synchronized修饰保证同时只会有一个线程访问,Request线程会接受屏幕按时间输入的请求并调用CubbyHole的put()方法加入请求队列或建立新的电梯线程,电梯线程会调用CubbyHole的get()和getconcrete()方法从请求队列中获得请求并执行,电梯基本采用ALS算法,多线程的协同和同步的控制问题只会出现在CubbyHole中,通过wait()和notifyAll()可以实现线程的交互,synchronized则解决了同步问题。

第三次作业架构分析

平衡性

在功能设计和性能设计的平衡上,笔者都没有追求极致故还算平衡,调度算法上没有特别具体的设计,Elevator会调用get()方法,具体哪个电梯线程先调度则随机,然后电梯会优先送离得最近的请求,如果上下一样近则随机选取一个方向,由于电梯具体情况太复杂故很多地方采用了随机策略,效果也不会太差。

可拓展性

本次作业电梯会有楼层限制,所以会出现部分请求出现换乘的情况,笔者在请求进入请求队列前就会根据打好的表将需要换乘的请求拆分,并在第一个请求完成后将第二个请求加入请求队列,故在拓展性上存在很大限制,且Elevator类和CubbyHole类耦合较紧。

SOLID设计原则

  • SRP原则较为符合,笔者的三个类设计目标清晰且分类明确。

  • OCP原则笔者完全没有实现,在第二次作业和第三次作业的更迭中我都多少的修改了原本的代码,还是扩展性存在问题,在后续单元应该持续改进这部分问题。

  • LOD原则和LSP原则笔者还是存在类与类之间耦合的问题,Elevator和CubbyHole由于特定的get类的方法和特定参数的传入而耦合,笔者认为应该在另一个调度类里实现请求的调度,分别与Elevator和CubbyHole进行交互,可以极大减少两者的耦合,也能够一定程度提高扩展性。

  • ISP原则,本次作业未使用接口。

基于度量程序结构分析

Homework1&Homework2

Method ev(G) IF_NEST iv(G) LOC v(G)
CubbyHole.CubbyHole() 1 0 1 3 1
CubbyHole.checkEmpty() 1 0 2 3 2
CubbyHole.get() 3 1 3 13 4
CubbyHole.getconcrete(int,boolean) 5 3 8 17 8
CubbyHole.put(PersonRequest) 1 0 1 4 1
CubbyHole.setEmpty(boolean) 1 0 1 4 1
Elevator.Elevator(CubbyHole) 1 0 1 10 2
Elevator.directioncheck() 1 1 1 7 5
Elevator.doorclose() 1 1 2 7 2
Elevator.dooropen() 1 1 2 7 2
Elevator.elevatorcheck() 3 2 7 26 8
Elevator.elevatorrun() 1 1 1 10 2
Elevator.elevatorwait(int) 1 0 2 7 2
Elevator.personin(PersonRequest) 1 0 1 5 1
Elevator.personout(PersonRequest) 1 0 1 4 1
Elevator.run() 5 1 8 28 11
Elevator.setDirection(int,int) 1 0 1 3 1
Main.main(String[]) 1 0 1 8 1
Request.Request(CubbyHole) 1 0 1 3 1
Request.run() 3 1 4 17 4
Class CSOA LOC OCavg OSavg WMC
CubbyHole 20 48 2 3.67 12
Elevator 110 125 2.64 6.64 29
Main 13 10 1 6 1
Request 93 23 2 5.5 4

由method分析,Elevator类里的run()方法和CubbyHole里的getconcrete()方法复杂度太高,而且这两个方法耦合度高,前两次作业基本完全一样,第二次作业只是在第一次的基础上加了多个电梯,所以存在相同的问题。

Homework3

Method ev(G) IF_NEST iv(G) LOC v(G)
CubbyHole.CubbyHole() 1 0 3 10 3
CubbyHole.checkEmpty() 1 0 3 3 3
CubbyHole.get(int) 6 1 8 29 11
CubbyHole.getconcrete(int,boolean,int) 5 3 9 18 9
CubbyHole.process(PersonRequest) 2 2 19 33 21
CubbyHole.put(PersonRequest) 1 0 1 5 1
CubbyHole.setEmpty(boolean) 1 0 1 4 1
CubbyHole.transfer(int) 1 1 2 8 2
Elevator.Elevator(CubbyHole,String,int,int,int) 1 0 3 21 4
Elevator.checknotfull() 2 1 2 6 2
Elevator.directioncheck() 1 1 1 7 5
Elevator.doorclose() 1 1 2 7 2
Elevator.dooropen() 1 1 2 7 2
Elevator.elevatorcheck() 4 2 9 34 9
Elevator.elevatorrun() 1 2 1 17 4
Elevator.elevatorwait(int) 1 0 2 7 2
Elevator.personin(PersonRequest) 1 0 1 5 1
Elevator.personout(PersonRequest) 1 0 1 5 1
Elevator.run() 5 2 9 30 12
Elevator.setDirection(int,int) 1 0 1 3 1
Main.main(String[]) 1 0 1 12 1
Output.println(String) 1 0 1 3 1
Producer.Producer(CubbyHole) 1 0 1 3 1
Producer.run() 3 3 7 40 8
Class CSOA LOC OCavg OSavg WMC
CubbyHole 25 119 3.88 9.5 31
Elevator 117 168 3.17 8.25 38
Main 13 14 1 10 1
Output 13 5 1 1 1
Producer 93 46 4 15.5 8

第二次作业中存在的问题中在第三次中由于迭代依然存在,且CubbyHole中新增的process()方法复杂度也很高,process方法是用来将换乘请求拆分的,Elevator中的elevatorcheck()方法复杂度也提升,新增加了一个Output类来保证输出的同步,类的分析中Elevator太复杂,包含了太多东西,应该合理拆分,即把调度新增一个类,而 Elevator类只管理电梯的状态和运行。

程序bug分析

三次作业的bug笔者在本地中测都发现并解决,所以幸运没有在强测和互测中错误

  • 第一次作业的的bug主要是多线程之间的同步问题,开始没有太理解wait和notifyall的作用,导致经常死锁且当时不太会多线程的调试,处于摸索阶段。
  • 第二次作业中测发现了一个明显的bug,电梯正常捎带时会判断是否超载,但在接主请求时不会判断,导致电梯上可能存在八个人。
  • 第三次作业存在两个bug,均是关于死锁的,比如A电梯在get时没有得到想要的请求开始wait,别的电梯get到对应的请求并执行退出后没有唤醒A电梯就导致A电梯无法退出,另一个bug情况基本类似,还是对多线程没有理解透彻。

互测策略

本单元的互测我并没有特别针对性策略,只设计了比如在同一时间点突然进入大量请求的极端数据和一些普通常规数据,多线程的bug常常不能复现也是一个问题。

心得体会

本单元第一次接触多线程,尤其是在多线程的调试上下了很大功夫,刚开始学习不明白多线程的意义,在三次作业的迭代中和os对进程线程的学习,逐渐了解了进程和线程的实际操作和意义,这单元的电梯也是我用程序写的最接近实际生活的小项目了,尤其是性能和功能的平衡上,不能一味追求性能而舍弃了本质的需要。这次多线程的第一次作业我花费的时间最长(主要也是开始半天不知道多线程怎么具体操作),第二次作业第三次作业都是在第一次作业的架构上修改部分代码得到的,花的时间少得多,这也说明了一个良好的根本架构的重要性,要是还想第一单元三次作业重构两次那就完全没有迭代的意义了,本单元比上单元迭代方面真的进步很大。然后在每次的研讨课上我也收获了很多,十分感谢每次研讨课愿意分享自己知识的同学,一个人快乐的OO日子的Unit2就结束啦!!

posted @ 2020-04-14 23:10  不思进取i  阅读(143)  评论(0编辑  收藏  举报