代码改变世界

oo第二次总结

2019-04-23 23:23  淑芬狗带  阅读(201)  评论(0编辑  收藏  举报

1.设计策略

第一次电梯作业是傻瓜电梯,就是先来的用户请求先被电梯完全执行,再执行后面的请求。这是一种很简单的生产者消费者的模型。我构造了两个线程,输入线程和调度器线程,还构造了一个请求队列可以插入、取出请求,两个改变队列状态的方法要加同步锁,输入线程负责读取控制台输入,将请求插入请求队列,调度器线程从队列取出请求,并改变电梯对象的状态,并进行输出。这种设计是投机取巧,相当于把调度器对象作为电梯,电梯对象名存实亡。所以这就导致我在写第二次电梯时就只能进行重构。

第二次电梯作业是有顺路捎带功能的电梯。这次进行了代码重构。设计了三个线程:输入线程、调度器线程、电梯线程,两种请求队列(第一种是输入线程项线程放入请求,调度器从中取请求,其实就是第一次电梯作业的队列(用户请求队列),还有一个是电梯捎带请求时将原请求插入队列,然后执行完捎带的请求就将原请求又取出来继续执行(命名为电梯请求队列))。调度器线程不断地扫描请求队列与电梯状态对比看是否符合捎带,如果符合就把这个请求插到电梯请求队列,如果队列为空调度器线程等待。电梯线程从电梯请求队列取出请求执行,如果队列为空电梯线程就等待。

第三次电梯作业是实现三部有顺路捎带功能的电梯,这三部电梯的某些性质不一样(运动速度、停靠楼层、最大容纳人数)。这次作业可以不用重构,但是电梯类需要改一下,添加一些属性:运动速度、停靠楼层、最大容纳人数。其他的设计与第二次电梯作业一样。为了能满足换乘请求,输入线程在插入请求时,将不能直达的请求拆分成几个分段请求,执行完一段请求,就将下一段请求加入请求队列由调度器进行调度执行。

2.基于度量来分析自己的程序结构

第一次电梯UML及复杂度:

 这次的电梯是傻瓜调度策略,实现过程很简单,类复杂度、方法复杂度都低

SOLID原则分析:

SRP(单一责任原则):符合。复杂度很低,功能比较简单,每个类都只负责一个功能;

OCP(开放封闭原则):不符合。电梯没有使用线程设计,如果要扩展功能必须修改电梯类设计

LSP(里氏替换原则):没有使用继承。

ISP(接口分离原则):没有使用自定义接口。

DIP(依赖倒置原则):没有使用抽象类。

第二次电梯UML及复杂度:

 这次是实现顺路捎带的电梯,需要实现三个线程新增电梯线程,调度器线程要不断扫描队列判断是否符合捎带,电梯线程的复杂度较高

SOLID原则分析:

SRP(单一责任原则):基本符合。队列用于管理请求、调度器负责调度请求、电梯负责执行

OCP(开放封闭原则):不符合。电梯类的某些属性(如运行速度)不能通过改变类属性来改变

LSP(里氏替换原则):没有使用继承。

ISP(接口分离原则):没有使用自定义接口。

DIP(依赖倒置原则):没有使用抽象类。

第三次电梯UML及复杂度:

 这次的请求队列类,电梯类,调度器类复杂度都比较高

SOLID原则分析:

SRP(单一责任原则):不符合。RequestTray类需要分割不可直达请求,还需要管理请求的队列

OCP(开放封闭原则):基本符合。

LSP(里氏替换原则):没有使用继承。

ISP(接口分离原则):没有使用自定义接口。

DIP(依赖倒置原则):没有使用抽象类。

3.分析程序的bug分析未通过的公测用例和被互测发现的bug

共有的问题:

这三次的测试中总会出现REAL_TIME_LIMIT_EXCEED,这是因为还有线程没有停止,必须再程序结束时停下所有的进程:有的时候,因为某些程序的某些错误, 会导致某些进程结束判断永远为假,进程无法结束;

第二、三次作业CPU_TIME_LIMIT_EXCEED错误:在请求队列为空时调度器、电梯线程在不断的循环,这样会消耗大量CPU运行时间,导致这个错误

这三次电梯作业一般不会出现wrong answer这种错误;

第二、三次作业因为是智能化的电梯,如果没有顺路捎带或者第三次作业的换乘算法不好就有可能会造成程序运行时间太久

4.测试程序的方法策略及有效性

使用自己的测试程序:这种方法有效性不高,其他人也会考虑到一些问题

阅读他人代码:这种方法效率比较低,需要弄清楚别人程序的结构,线程的设计

5.心得体会

 这三次的电梯作业加深了我对多线程的理解。对线程安全的保证主要是要保证在修改共享对象时线程安全。对象状态改变方法需要加锁来保证不会发生同步错误;

我这三次作业调试时采用了一个比较简单的调试方法,就是在每个线程结束时弄一条输出语句表示进程结束,这样我就可以清楚的弄清楚那些线程没有正常结束;

我后面两次电梯作业的电梯对象都是采用线程设计,真正模拟电梯的上行下行活动,各个线程之间不能直接互相改变状态,线程之间的联系是依靠共享对象的,我的共享对象就是请求队列,输入线程和调度器线程之间共享用户请求队列,调度器和电梯线程之间的共享对象是电梯请求队列。