【面向对象设计与构造】第二次博客作业

【面向对象设计与构造】第二次博客作业


一、多线程协同和同步控制策略

1. 第五次作业

第五次作业设计了一套由3 部电梯组成的多电梯调度系统,通过采用线程机制, 在第三次作业所实现程序的基础上完成新的调度系统程序。本次作业为调度器,3部电梯都各自新建了独立的线程来进行工作,主线程则处理输入请求,充当请求模拟器的角色,建立了公共的线程安全的队列reqQueue作为托盘供不同线程共享使用。对于某些需要等待一段时间才能调度的楼层请求,程序也各自新建了线程来等待空闲电梯或者可捎带电梯进行调度。

本次作业的线程同步问题主要体现在对于线程安全的请求队列的访问上,由于有多个线程同时对该队列进行操作,所以对关键的方法都加上了synchronized关键字进行同步。

2. 第六次作业

本次作业实现了一个文件系统监控程序,针对给定监控范围内的监控对象,以扫描方式探查监控对象相关属性的变化,从而触发规定的处理动作。程序为输入和输出处理各新建了一个类,输入处理设为单独的线程,针对每一个输入的监控任务,程序进行格式检查后对于符合要求的输入会新建一个独立的触发器线程进行监控。

本次作业的线程同步问题主要体现在SafeFile类的构建上,由于多个线程需要不断对文件信息进行读取,同时File类本身并非线程安全类,所以对SafeFile类的方法都加上了synchronized关键字进行同步,并将这些方法都定义为静态方法。

3. 第七次作业

本次作业模拟了出租车的乘客呼叫与应答系统。乘客可以发出乘车请求,然后系统会给出3秒的时间用来让指定范围内的出租车进行抢单,然后系统会根据一定的调度规则来选择一辆符合要求的出租车,最后被派单的出租车会按照最短路径到达乘客乘车点,最后载上乘客按照最短路径到达目的地。程序对于100辆出租车每辆各有一个独立的线程,请求输入处理及队列管理者为一个线程,加入队列后会新建一个分配线程,负责抢单窗口的新建,以及最后订单的分配。

为了保证线程的安全,分配线程和出租车线程的部分方法加上了synchronized,保证对共享资源的访问不会出错。

二、度量分析

1. 第五次作业

类图

由类图可以看出本次作业的优点在于对前两次电梯作业的电梯调度器类进行了很好的继承,并且实现了ElevatorInterface接口,各个类之间实现了比较好的交互和协作,缺点在于Main类稍显庞大,应该将请求模拟器单独抽离出来形成一个类,而不应该放在Main类中。

度量分析

由分析图可以看出,在电梯调度线程的run()方法内代码过多,逻辑过于复杂,嵌套过深,使得整体的复杂度过高。

时序图

2. 第六次作业

类图

度量分析

由分析图可以看出本次作业对于监控对象进行输入格式的检查部分代码量过大,由于需要对监控任务和触发器的搭配,相同的监控请求等多种情况进行检查,所以导致复杂度过高,应该考虑将不同的情况进行分类,抽象为不同的方法进行检查。

时序图

3 第七次作业

类图

本次作业为了符合课程要求的设计原则,对代码风格和代码细节方面进行了许多规范和优化,特别新建了一个Constant接口用以保存程序中多次用到的常量定义和方法,从而增加了程序的可读性,使之更加符合显示表达原则和重用原则。

度量分析

本次作业的复杂度超过范围主要是因为下发的gui.java代码复杂度过高,程序的其他部分代码复杂度整体适中。

时序图

三、程序bug分析

1. 第五次作业

第五次作业在公测和互测中并未发现bug,自己在进行测试的过程中发现电梯在处理同一时刻的多个请求时,由于多个线程同时进行在时间上的不确定性,因此在进行捎带电梯和空闲电梯的选择时不同的运行有时会得到不同的结果,这可以算作是不可避免的问题,所以并未进行修复。

2. 第六次作业

本次作业中的bug之一是在编写程序的输出处理时由于没有认真检查和测试,出现了输出形式方面的错误,这种问题只要认真研读指导书并认真检查即可避免,实在可惜。

另一处bug则是由于程序设计时没有考虑文件IO所占用的时间过多且代码存在逻辑方面的漏洞,因此在某些特殊情况下会表现出问题。

3. 第七次作业

第七次作业在公测和互测中并未发现bug,但自己在编写程序时发现对于出租车运行时间的控制并不是很准确,为了减小输出时的误差只好按规定对输出进行了符合要求的取整。

四、bug分析策略

一是要结合Readme文档认真读代码,分析代码的结构,在此基础上发现问题,然后对症下药,通过相应的测试样例来进行验证。这种方法虽然需要花费较多的精力,但是可以发现一些普通测试样例难以发现的问题,具有很好的针对性。时在读代码的过程中也可以对程序的代码风格以及是否符合课程的设计规则进行检查和评估。

二是通过编写测试程序和测试样例对程序进行全方位的功能性测试,除了正常性的功能测试外,还要对程序的一些边界情况进行测试,检查程序功能是否正确以及是否会发生crash。

三是再次认真读Readme文档,针对作者在文档中规定的各种特殊情况以及相应的处理方式在程序中进行一一验证,发现可能存在的其他问题。

五、心得体会

首先,在面向对象编程和多线程并发编程的学习方面,每次作业对于我们面向对象编程思维和编程能力的训练确有很大帮助,同时,程序不仅要保证能够实现正确的功能,同时也要对程序运行的时间和性能等其他方面进行综合的考虑。通过这几周的学习,我们已经能够用java来实现简单的面向对象的多线程程序,尽管现在写出的程序可能存在许多不足,但对于我们今后的学习来说无疑奠定了十分重要的基础。

其次,通过每一次的互测,我看到了许多风格不同的代码。一方面,在读这些代码的过程中,除了能够发现对方程序的问题,同时也能从中学到很多好的设计思路和设计风格;另一方面,这多次的代码测试过程也愈发凸显出拥有一个良好的代码风格的重要性,对于最后一次课程所提示出的设计规范,我认为我们不仅仅应该在作业中遵守,更应该将其作为一种习惯融入到我们今后写代码的过程中去。

最后,对于每次作业的编写,我们都应该本着“三思而后行”的原则,在多次阅读过指导书和讨论区的问题,对本次作业的要求有一个充分而全面的认识,同时对于程序的整体框架有一个构思之后,再开始写代码,切不可急功近利,只粗略看过一次指导书便匆匆茫茫开始写程序,这样写出的程序在多数情况下都会存在许多的问题。

原文地址:https://www.cnblogs.com/David-Liu-/p/8981507.html