OO第二单元总结

第一次作业

类图

 

代码规模

 

复杂度

 

协作图

  由于需求是一部电梯,所以只需要考虑线程的新建和运行。我采用了生产者-消费者模型,输入和处理相对独立。但是电梯类被我内置了过多方法,显得有些臃肿。至于捎带规则,考虑到需要输出电梯的每一步移动,我采用逐层扫描的方式,每到一层就查询是否有新的可捎带请求。这次实现比较简单,在互测环节没有查出bug,也没有被hack到。

 

第二次作业

类图

 

代码规模

 

复杂度

 

协作图

  第二次作业在上次的基础上增加了自定义电梯数的需求,我在主类中读取到电梯数之后便启动乘客请求读取线程,其余部分与第一次类似。这次我将输出电梯动作的方法封装成一个单独的类,复杂度有所降低。虽然增加了电梯数目,理应有更加高效的调度算法,但是我仍然沿用第一次作业的方式,放任电梯线程自由竞争。值得注意的是,这次的需求中有限制单部电梯的载客量上限,在中测时我才发现此处存在bug。

 

第三次作业

类图

 

代码规模

 

复杂度

 

协作图

  第三次作业与之前最大的不同是增加了新增电梯指令和换乘需求。之前的作业明确规定了输入请求的顺序和种类,所以只要把握好方法执行的顺序即可。这次出现新增电梯指令的位置不定,对输入的解析有更高要求。如上图,我将输入的职责转交给主线程,由它决定何时启用新电梯。同时,针对换乘需求,设计一个管理换乘逻辑的类Getfn,确定是否能由某类电梯担任换乘任务,确保输入的任意请求仅经过一次换乘就能到达目的楼层。由于疏忽,本次作业出现了一个严重的bug:电梯在换乘队列取请求时不受最大人数限制。这直接导致在强测和互测中的失分。

 

总结

心得

  经过第一单元的洗礼,算是对面向对象编程有了一点感觉,在设计各个类时有了比较明确和独立的目的。刚开始接触到多线程有些一头雾水,但是一旦掌握了多线程的特点,设计的难度大大降低。这几次作业中,还有一个令人头疼的点是多线程的调试。printf大法虽然好,但是在时间上花费巨大。直到提交完第三次作业,才了解到更多更便捷的多线程调试方法,后悔当初没有花时间搜寻。

关于SOLID

  在本单元的设计中,唯一显得较臃肿的是电梯类,尽管后来输出方法被独立出去,其中含有的电梯运动逻辑相关方法使得设计没能满足单一责任原则的要求;开放封闭方面,几次作业的需求变化促使我对代码做出较多基础的修改,尤其是电梯类的内部方法逻辑;在第三次作业中出现了三种不同职责和功能的电梯,我采用继承的方式扩展和改装电梯的运行逻辑,但也仅限于修改重写判断可停靠楼层的方法,基本符合里氏替换原则;接口隔离和依赖倒置方面,我没有使用到基于接口实现或抽象类实现的设计方法,所以没有涉及。

关于线程安全

  由于多线程概念和需求的引入,线程安全问题也让许多同学感到头疼。所幸在我的设计中,唯一可能导致线程安全问题的是共享类缓冲区(Relif),而输入线程和电梯线程涉及的方法和属性相对独立,降低了线程安全问题出现的可能性。至于电梯线程都需要访问的方法,通过添加synchronized关键字和锁,使得运行时没有出现线程安全问题。

posted @ 2020-04-16 19:33  longmixl  阅读(107)  评论(0编辑  收藏  举报