OO第二单元总结

(1)从多线程的协同和同步控制方面,分析和总结自己三次作业的设计策略

第一次作业采用SSTF策略,InputHandler和Elevator两个线程共享一个RequestList。InputHandler处理输入请求,Elevator负责运行,RequestList接受、存放和调度请求。后两次作业与第一次架构基本相同。

(2)从功能设计和性能设计的平衡方面,总结自己第三次作业架构设计的可扩展性

第三次作业线程上架构与第一次作业类似,不同之处是增加了三个电梯类,并修改原电梯类,让ABC三种电梯都继承自原电梯类。同时增加了一个用于查换乘表的类。

  • Main:创建和启动线程;

  • RequestList:接受、存放和调度请求;

  • InputHandler:此线程来实现读取控制台的请求并将数据存入Queue队列;

  • Elevator:电梯父类;

  • ElevatorA\ElevatorB\ElevatorC:不同规格的电梯;

  • TransferTable:返回换乘策略。

因为写崩了所以应该谈不上有可扩展性。。。

SOLID
  1. 单一职责原则 Single Responsibility Principle:

每个类基本有单一的职责,但内部还可以细化,尤其是RequestList一直负责所有调度工作。

  1. Open Closed Principle开闭原则:

每次迭代都修改了Elevator类。特别是run方法,第一次作业就写的比较复杂,后面修改的时候也有些混乱。我认为之后作业要更多地在第一次就想好后面可能的迭代方向,而不是只着眼完成这次的功能。

  1. Liskov Substitution Principle里氏替换原则:

电梯各个子类基本上只是传了不同参数给父类,因此与父类功能一致。

  1. Interface Segregation Principle接口分离原则:

不知道咋评价,因为各个类之间交互关系比较明确,好像涉及不到两个类同时用一个方法获取感兴趣的信息。

  1. Dependency Inversion Principle依赖倒置原则:

同上,在这次作业中没有太涉及到这个问题

(3)基于度量分析自己的程序结构

  • 第一次作业

复杂度:处理电梯行为的几个函数复杂度较高,比如乘客进出、电梯的run、获取下一波乘客。

 

OO第二单元总结_第1张图片

OO第二单元总结_第2张图片

UML类图:

OO第二单元总结_第3张图片

  • 第二次作业

复杂度:

OO第二单元总结_第4张图片

OO第二单元总结_第5张图片

UML类图:

OO第二单元总结_第6张图片

  • 第三次作业

复杂度:

OO第二单元总结_第7张图片

OO第二单元总结_第8张图片

OO第二单元总结_第9张图片

UML类图:

OO第二单元总结_第10张图片

(4)分析自己程序的bug

  • 第一次作业

    bug:为了解决线程安全问题把synchronized的范围放得很大,结果强测性能分几乎都是0。

    解决办法:把synchronized范围从elevator run的循环缩小到requestList的add\remove操作。

  • 第二次作业

    bug:电梯获取请求时调用requestList的getInBundle,但这个函数会把所有符合条件的人都塞给电梯。如果超过电梯运载能力,无法满足的请求会丢失,导致有一些乘客没进电梯。

    解决办法:一开始想让电梯把人放回队列,但是会超时。改为把电梯剩余空间传给getInBundle,让requestList可以分配给电梯合适数目的乘客。

  • 第三次作业

    bug:大概率是出现了死锁,但没有de出来。

(5)分析自己发现别人程序bug所采用的策略

因为太菜所以主要在分析自己的bug(逃

(6)心得体会

经过这一章还是对多线程不太理解,很多地方是凭感觉加synchronized,并不是很理解具体发生了什么。多线程部分最大的困难可能是难以debug。在讨论课之后尝试用JProfiler,但是并没有定位到第三次作业死锁在哪个环节产生,总之就是比较懵逼。。。其实第一次作业实现的时候就觉得电梯的run,getInOut,getInBundle几个环节之间逻辑关系不是很清晰,第三次作业为了实现换乘,更提高了控制逻辑的复杂度,导致bug是必然的。第二次作业互测时看到一些用dispatcher制定策略的代码,想重构但是自己实现的时候还是很懵,不清楚功能分离的边界在哪里。希望能看看大佬代码梳理下思路。

 

你可能感兴趣的:(OO第二单元总结)