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

注:UML图中每个划分了的圆角矩形代表一个类或接口,箭头可代表创建、访问数据等行为。类的图形内部分为3个部分,从上到下依次是类的名称、类包含的实例变量(属性)、类实现的方法。接口图形内部只分2个部分,上方为接口名,下方为接口定义的抽象方法。箭头上的注释进一步解释了类之间的关系。

作业1:多项式运算

两处红色的问题都出自checkformat方法。该方法圈复杂度高,块嵌套深度高。原因在于自己的格式检查没有使用推荐的正则表达式,依然使用了传统的有限状态机。这就容易造成逻辑复杂、代码过长。而且,该方法完成的功能已经不局限于格式检查,而包含了信息提取的代码,同时实例化了term, poly, compute类的对象。

第一次作业初步体现了面向对象思维。主类的main方法只负责读取输入,之后创建了check类并将工作转交给check。checkformat方法则有“全能”的问题,负责了格式检查和输入提取,同时创建了term, poly, compute3个类的对象。被提取的输入会被整理为term和poly对象。最终,创建compute类下的对象,计算并输出结果。

作业2:单部傻瓜电梯

第二次作业较第一次有所改观。大部分方法的规模控制在30行以下。最长的方法为main,行数降低为120行。main方法圈复杂度较高。

第二次作业的进步之处在于使用了正则表达式进行格式检查,同时用String类下的split方法对有效输入的各部分信息进行分离提取。存在的问题是main方法承担了较多工作,一些无法通过简单检查正则表达式就能识别的错误仍需要在main方法中检查并报错。将这部分功能独立出来会简化main的逻辑。

由于课件中已经给出了参考设计,并明确要求实现5个类,因此设计思路基本遵循了课件。不足之处在于调度器dispatcher对同质请求的判断只通过了队列前后请求信息,而没有利用楼层、电梯按钮信息,并未完全符合老师的初衷。而且这种判断方法也容易导致BUG出现。

作业3:单部ALS电梯

问题比较严重的是main方法与schedule方法。main方法圈复杂度高,问题与第二次作业相似,都是把对无效请求的部分判断逻辑放入了其中。schedule方法块嵌套深度高,尽管将捎带请求的判断独立写了方法,但是针对电梯内请求的情况提炼总结不够,导致判断语句嵌套深度高。

由于楼层类没有实现预定功能,且出现BUG,本次作业没有将其实例化。对于继承、多态相关的设计要求均予以实现。为此,dispatcher的各方法做了较大的调整。

总结:

自己在总体设计上的优点是尽力按照面向对象的思维进行总体设计和编程,让各个对象管理自己的数据,减少数据传输,功能合理分散。没有出现自己互测拿到的那种一个方法分担了90%左右工作的情况。

缺点在于在拿到作业之初,一般不会进行书面的总体设计,导致经常性的代码改动,甚至推倒重来,在大规模开发中不可取。

一些细节并没有完全遵循指导书的意思,导致后续作业的工作量增加。(第二次作业的schedule方法就是一个例子)

第3次作业的楼层类属于鸡肋,没有被实例化过,这种做法尽管在同学中比较普遍,而且我也拿到过这样的代码,但是很不可取。

个别方法的判断逻辑过于复杂,判断和循环嵌套较深。具体的方法、类上文已详细指出。

(2)分析自己程序的BUG

第1周作业:

BUG1:空多项式输出{(0,0)},指导书要求只输出0

BUG2:同一个多项式的项之间不检查是否缺失和多逗号

BUG3:多项式之间运算符缺失不报错,按加法处理。

分析:

BUG主要是格式检查不仔细、输出格式与指导书不符。问题所在的类是check,方法是checkformat。

checkformat方法没有使用推荐的正则表达式,依然使用了“计算机组成”课中学习和使用过的有限状态机。实现有限状态机的代码逻辑会比较复杂,其可靠性很大程度上取决于编程者在绘制状态转移图时能否不重不漏、逻辑缜密。一旦需求变更或发现BUG,代码的修改也是一个很困难、痛苦的过程。自己设计时擅自简化了一部分逻辑,并且没有辨析哪些属于指导书硬性要求,导致产生BUG。

分类树分析:

BUG更多发生在“输入格式不符合规定”分支上,这与之前的总结相吻合。

第2周作业:

BUG1:格式检查不支持前导零、正号。

BUG2:输入楼层为0时程序crash

BUG3:时间为很大的整数时计算出错,时间越界不报错

BUG4:楼层类数组实现逻辑出错,在特定样例下crash

BUG5:同质请求判断不准确

分析:错误种类包括格式检查出错、同质请求逻辑不正确。出错类和方法包括:

类名

方法名

功能

strprocess

checkformat

输入字符串格式检查

floor

所有

楼层号和上行、下行按钮

dispatcher

check2

同质请求的判断

在设计楼层类时,不明确这个类的真正作用,设计了上下行按钮却没有将其纳入判断逻辑,而且数组的基本知识掌握不牢固,发生了数组越界异常的惨剧。于是第3周的作业干脆取缔了这个类,尽管可能与老师的软性设计要求相违背,但是客观上提高了程序的可靠性。

分类树分析:

“数字范围测试”被发现的BUG居多。主要是忽略了楼层为0的情况、对时间没有设上限。

第3周作业:

BUG1:没有实现多个同层捎带请求只开关一次门

BUG2:主请求选择错误

BUG3:同质请求判断出错

分析:BUG出现在本次作业的重难点——捎带与主请求选择上。

类名

方法名

功能

als

schedule

ALS策略调度电梯

als

judge_f

判断楼层请求能否被捎带

als

jucge_e

判断电梯请求能否被捎带

分类树分析:

“合法输入-正常情况测试-多个捎带”被发现的BUG居多。自己对代码逻辑擅自简化,没有严格实现指导书中关于多个请求捎带的要求。

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

策略1:阅读理解正则表达式

对用户输入进行格式检查是这3次作业的共性问题。错误分类树在格式错误上也设置了不少的扣分点。笔者3次抽到的代码都是利用正则表达式完成的格式检查,因此要想发现对方格式检查方面的错误,检查正则表达式是最佳突破口。

策略2:明确硬性设计要求

为了强化学生对于面向对象思想的理解,每周的作业都会提出一些设计要求:第1次要求使用数组。第2次要求必须实现规定的5个类,不允许出现public的属性。第3次要求必须实现接口,重写和重载指定的方法。自己写代码时就要看清这些要求,同时拿到互测代码后也要严格检查。利用eclipse的outline窗口能够看到类、实例变量和方法,理清被测代码的设计结构,方便对设计要求的检查。

(4)心得体会

1)急于完成作业,没磨刀最后误了砍柴工

每周的作业一发布,自己就着急忙慌地打开IDE敲代码。殊不知在写程序前没有对总体开发做出明确规划的话,往往会频繁改变自己的设计,补上本应在写代码前做的功课。自己的状态经常是周末写写停停,然后在周日的下午将一切推倒重来,最终在周一的晚上完成了一个基础性的设计,通过了正常功能的测试样例。周二针对答疑群和Issue上的样例测试自己的代码,发现能修的BUG就修掉。周三则写其他课作业或望着IDE发呆。其实前几次作业的时间完全来得及,在开始开发之前把各个类的实例变量、方法想清楚,打好草稿是更值得推荐的做法。《Head First Java》甚至推荐学习者先写伪码和测试码,最后再写正常的程序代码。这也是“磨刀不误砍柴工”思想的一种体现。

2)总体设计要严格遵守指导书,不得偷工减料

“顾客就是上帝”的俗语在编程领域一样适用。指导书提出的要求,作为学生就应该坚决贯彻落实。如果偷工减料,最后吃亏的、学不到本事的还是自己。第二次作业对调度器类给出了更加详细的设计方案,包括command和schedule两个方法,而我没有实现。结果第三次要求继承上次的调度器并重写父类schedule方法的硬性要求害的我把整个类都重写了。第三次要求将可捎带请求放入集合,我改成遇见一条执行一条,最后同层只开一次门的问题未能完美解决。

3)debug只有进行时没有完成时

要问我每周三是怎样度过的,我的回答竟是如此颓废:盯着电脑屏幕度过的。一种可能是发现不了bug在哪里,想到什么测什么,或者直接从微信答疑群和Issue上借用别人的数据。一种可能是bug太难修复,自己直接就放弃了治疗。这不是一个二十出头的年轻人应该有的状态。一方面,只要提交窗口没关,就还有补救的机会。发现bug就要积极去修复,而不是让畏难情绪做了自己的主。第3次作业针对BUG在周三奋战了一天,尽管最后没提交那个版本,但是这种精神值得带到后续的开发中。另一方面,程序都有出错的可能。自我测试期间对于同一个分支节点应该打破思维定势,多换几组样例,而不是过了一组就认为绝对不存在问题。例如第二次作业楼层为0导致crash和整数超长应报错却不报的问题完全是多换几组样例就能发现的问题,却在我的眼皮子底下溜走。栽了一次跟斗后总算认识到了自测的重要意义。

4)好逸恶劳思想作祟,仓促应战

辅导员早已多次强调过这门课程的难度非同小可,但是我却一直以“大二下学期还早”的假象欺骗自己。《Head First Java》虽然早就买了,但是直到假期最后一星期才拆开塑封,直到开学前都没有跑过一个自己写的java程序。看到第一次作业的题目后,我吓得头皮发麻、直冒冷汗,因为自己已经有半年没有好好写过高级语言程序了。(计组实验写的是HDL语言)而且我发现自己一周看下来的java语法知识连应付这次作业都不够格。于是我第二天卸载了所有手机游戏,停止了一切娱乐活动,并做好了熬夜奋战的准备。“临阵磨枪,不亮也光。”我最终还是在ddl之前完成了能通过大多数正常功能样例的程序。但是这次的教训值得吸取。假如我能在假期就将自己的电脑配置好java环境、把第5、6章的程序自己写一遍、跑一遍,那么第一次作业来临时绝对会比现在沉稳很多。

5)学会使用搜索引擎

计算机专业的一大特点,在于书本不会教给你一切。《Head First Java》等参考书是为学习Java语言设计的,并不是Java百科。事实上,真正的百科不在书本里,而在网络上。想实现一个功能而又在书中找不到相关知识时,不妨搜索一下,也许有的人早就为此撰写过一篇博客。

OO博客作业1:第1-3周作业总结的更多相关文章

  1. OO博客总结——OO落下帷幕

    OO博客总结--OO落下帷幕 凡此过往,皆为序章. 不知不觉OO课程即将落下帷幕,一路坎坎坷坷磕磕绊绊,可算是要结束了,心里终于松了一口气,也有小小的不甘和遗憾.凡此过往,皆为序章.特殊的线上OO课程 ...

  2. OO博客作业-《JML之卷》

    OO第三单元小结 一.JML语言理论基础以及应用工具链情况梳理 一句话来说,JML就是用于对JAVA程序设计逻辑的预先约定的一种语言,以便正确严格高效地完成程序以及展开测试,这在不能容忍细微错误的工程 ...

  3. OO博客作业2:第5-7周作业总结

    (1)从多线程的协同和同步控制方面,分析和总结自己三次作业来的设计策略及其变化. 第5次作业:多线程电梯 基本照搬了课件上“生产者-消费者”模型的设计策略,将InputHandler设计为生产者线程, ...

  4. 第二次oo博客作业--多线程电梯

    这次的系列作业是写一个电梯调度,主要目的是让我们熟悉多线程. 第一次作业是一个傻瓜电梯的调度问题,要求也很简单,即每次接一个人就行了.我只用了两个线程,一个是输入线程,一个是电梯线程,输入线程负责从标 ...

  5. 小菜鸡儿的第三次OO博客

    规格化设计历史 规格化设计的历史目前网上的资料并不多,百度谷歌必应也表示无能为力...... 在这里结合现实情况讲一讲自己对程序规格化的理解,首先代码规格化对代码的影响是间接的,或许它不能让你代码里面 ...

  6. 接着继续(OO博客第四弹)

    .测试与JSF正确性论证 测试和JSF正确性论证是对一个程序进行检验的两种方式.测试是来的最直接的,输入合法的输入给出正确的提示,输入非法的输入给出错误信息反馈,直接就能很容易的了解程序的运行情况.但 ...

  7. OO博客作业3:第9-11周作业总结

    一.总结介绍规格化设计的大致发展历史和为什么得到了人们的重视 1.规格化设计的大致发展历史 规格化设计,又称契约式设计,最早由Bertrand Meyer于1986年提出,出自于<面向对象软件构 ...

  8. OO博客作业4:第13-14周作业总结

    一.论述测试与正确性论证的效果差异,比较其优缺点 测试是设计若干组测试用例,运行程序并检验其是否完成预期功能.测试是一种直接发现BUG的方法,可以准确断定什么样的BUG会发生,并通过辅助调试进一步确定 ...

  9. 第四次oo博客作业

    (1)本单元是撰写UML数据分析器,架构大致如下,在指导书要求的函数外,对于UmlClass类,Umlinterface类,以及状态机,顺序图这四个类重现构造一个类,这个类里有他们所需要的全部信息,另 ...

随机推荐

  1. 【redis专题(9)】事务

    Redis支持简单的事务,所谓简单是因为其不支持回滚(回滚是用队列模仿的),与mysql有以下区别 rollback与discard的区别: 如果已经成功执行了2条语句, 第3条语句出错 Rollba ...

  2. SQL SERVER启动步骤

    第一步 从注册表读取SQL SERVER启动信息 (1)Audit  Level:设置SQL SERVER是否记录用户登陆信息 Login Mode:设置SQL SERVER登陆类型是只接受windo ...

  3. ALTER添加列后,立即UPDATE该列会报错

    SQL 2008 R2 请看语句: ALTER TABLE #t ADD col2 INT UPDATE #t SET col2 = 0 报错:列名'col2'无效. 但如果紧接的是SELECT,一切 ...

  4. UITableView的分割线长短的控制

    UITableView的默认的cell的分割线左边没有顶满,而右边却顶满了.这样显示很难看.我需要让其左右两边都是未顶满状态,距离是20像素 // code1 if ([self.tableView ...

  5. Unity基础6 Shadow Map 阴影实现

    这篇实现来的有点墨迹,前前后后折腾零碎的时间折腾了半个月才才实现一个基本的shadow map流程,只能说是对原理理解更深刻一些,但离实际应用估计还需要做很多优化.这篇文章大致分析下shadow ma ...

  6. 如何指定一个计划和目标——6W

    作为一名IT人员,需要自己指定一个计划和目标,来保证完成进度和高效的完成任务. 参考管理学如何制作计划和目标的,套用过来,也是同样适用的.来先看看管理学的相关知识吧. 计划的概念:计划是为实现组织目标 ...

  7. Error response from daemon:###unable to delete ### (must be forced) - image is being used by stopped

    具体错误:Error response from daemon: conflict: unable to delete f2e2f7b8308b (must be forced) - image is ...

  8. SQlite的结构——存储管理

    在今天的商业应用中,主要有两种基本类型的DBMS(数据库管理系统)存储管理器: (1)DBMS直接与底层的面向磁盘的块模式设备驱动程序进行交互(通常称为原始模式访问); (2)DBMS使用标准的OS文 ...

  9. centos7下安装docker(14安装docker machine)

    之前我们做的实验都是在一个host上面的,其实在真正的环境中有多个host,容器在这些host上面启动,运行,停止和销毁,相关容器会通过网络相互通信,无论他们是否运行在相同的host上面. 对于这种歌 ...

  10. 【Java基础】char

    1.JAVA中,char占2字节,16位.可在存放汉字 2.char赋值 char a='a';  //任意单个字符,加单引号. char a='中';//任意单个中文字,加单引号. char a=1 ...