2019年北航OO第一次博客总结
一、基于度量对程序结构的分析
1. 第一次作业
1.1 基于类的分析的度量
首先,基于类的属性个数,方法个数,每个方法的规模,每个方法的控制分支数目,类总代码规模等特征对本次作业的结构进行分析。
1.2 基于类间内聚和耦合的度量
我使用了MetricsReloaded插件来对代码的复杂度进行了分析。
还有对于方法的复杂度分析由于篇幅原因没有贴出来,主要的指标为ev,iv,v三个指标,分别代表基本复杂度、模块设计复杂度以及模块判定结构复杂度,ev大代表代码非结构化程度高,难以模块化和维护。iv大代表模块间耦合度高,模块间难以隔离与复用,v大表示代码独立路径条数多,难于测试和维护。在做面向对象度量时,我们经常采用ck度量(Chidamber Kemerer)来度量耦合,内聚,封装等等特征。上表中wmc代表的是类的方法权重,表示一个类中所有方法的复杂度之和。显然越大说明越复杂。
1.3 UML图及结构点评
由于是第一次作业,因此对于面向对象的思想还不是特别熟悉,我这次将main类与Poly类写到了一起,其实应该分离,一个多项式的类,一个项的类,一个main入口类。整体来讲结构不是很好,而且有两个比较长的方法同时分支较多,同时也就造成了它们的独立路径数较多,模块复杂度较高。
2. 第二次作业
2.1 基于类的分析的度量
2.2 基于类间内聚和耦合的度量
我的高复杂度方法体现在输入处理,输出处理以及化简上,这次作业如何有效的化简是一个难点。
2.3 UML图及结构点评
本次作业的设计较为体现了面向对象的思想,设计了一个main入口类,多项式类,项类,因子类,以及其中由于因子是由底数和指数组成的,而指数又有多种形式,故设计了一个底数的抽象类base,将常数类const,幂函数类power,三角函数类triangle作为了base的子类,这样就可以将一个多项式一点点解析成项,因子,底数,指数等等。同时,由于每一个类都有共同的特点就是可求导,因此我设计了一个求导的接口Derivable,所有的类都实现了这个接口,这符合了java面向接口编程的思想,同时也提升了代码的规范性。
3. 第三次作业
3.1 基于类的分析的度量
3.2 基于类间内聚和耦合的度量
发现我的高复杂度的方法全部都是对于输入处理上,由此可见我的输入处理的不太好,写的十分面向过程且十分容易出错。
3.3 UML图及结构点评
本次作业的架构和上一次作业是完全一致的,因为上次作业时我就考虑到了程序可扩展性的特点。然而本次作业在加了表达式因子和嵌套因子后显得这个架构有一些问题。求导部分利用递归向下求导的方式倒是不难实现,此次作业最难的输入部分我处理的不是很好。这次输入的难点主要是出现了表达式因子和嵌套,我们如何用正则表达式来正确的识别和解析。我的想法是先找到所有非三角函数括号中最内层的括号,将其解析为一个多项式,这时再解析出该多项式内部的三角函数,把三角函数括号中嵌套的多项式因子解析到三角函数的属性中去,重复这个步骤直到没有括号为止。整个过程虽然可以实现但是十分复杂,十分面向过程且会有多分支,行数非常多的方法,复杂的正则表达式的存在。后来在讨论课上听说的用工厂模式或一个parser的类可以更好的实现该输入解析过程,parser类里面分别有对poly,item,factor的解析方法,高内聚低耦合避免了一大串if-else的出现。
二、Bug分析
1. 第一次作业
第一次作业我的强测没有出现WA的情况,但是被hack了12次(2同质),分别是\\s+匹配到\t和空格外的字符的情况、以及直接输入空格程序crash的情况,程序crash的原因是我在得到字符串之后直接进行了input.trim()操作,导致输入input变为空串程序crash,有两种更改方式,一种是直接把main方法里面的所有内容用try-catch保住,确保程序不会出现crash(这也是我后面两次作业的写法),另一种方法是在trim()后面再判断一次串是否为空。对于另外一个bug,我的正则里面写的是[ \\t]*然而还是出现了bug,这与我程序的设计结构密切相关,因为我再刚刚读入input的时候就用trim()去掉了两边的空白符,这样导致输入字符串两边的\v和\f无法有效的识别WF,造成了bug的出现。我的修改方式是先看所有的输入字符是否有非法字符,如果有的话直接输出WF即可。
2. 第二次作业
第一次作业我的强测没有出现WA的情况,但是也被hack了3次(2同质),分别是在输入符号处理中的if表达式中的||手误写成了&&,和对于输入错误的匹配没有识别出WF。仔细想想,这与我的设计结构也有着千丝万缕的联系。我对于输入的处理是在去掉了输入两边的空白字符后依据此时input.CharAt(0)来确定在前面添加"+"或者"+0",然而我没考虑到*x若在前面"+0"会造成本来是WF的数据变成合法,因此导致了bug。另外一个bug就是典型的一大段if-else造成的键盘误操作,这也体现了减少分支数量降低代码复杂度的必要性。
3. 第三次作业
第三次作业我的强测WA两个点,被hack了10次(强互测加起来2同质),分别是输入匹配时正则表达式少了一个[ \\t]*造成的有空格导致不匹配以及一个符号出现了问题。这两个问题的产生就与我的设计非常密切的相关了。我写了4个正则,其中最大的正则有6行,如此长的正则难免会不小心失误,写小正则把问题分开分析是避免这类错误的一个很好的方式。而另外一个符号错误则完全是由于我的输入写得太过复杂,括号来回匹配的逻辑,比如解析一个item,会返回一个poly.解析一个factor也会返回poly,而每个item都有其固定的符号,这次Bug的出现就是因为在解析item返回poly的时候没有考虑原来item的符号,而默认"+"造成了错误。由此可见,面向对象的设计模式,封装的好处就是减少耦合,减少出错点。
三、Hack策略
1. WF
前两次作业错误主要集中在WF上,这时候就可以手动设计测试样例,比如全空格,空串,只输入常数,输入x^0,0*x,si n(x),sin ( x ),+++1,++ 1,\f\v,BigInteger,爆栈,......等等,因为前两次作业正确性的实现上并不难,主要大家的出错点在对WF的处理上,因此我的这种策略有效性也很高,前两次作业共提交7个测试样例hack18人次。
2. 正确性问题
第三次作业强调正确性的问题,我也从正确性的问题入手,具体方法就是对于指导书上对本次实验要求的所有功能,先分别构造测试数据,在将各种模式组合起来,比如sin()里面有表达式,里面还有嵌套的sin(),再加一些项乘起来之类的。覆盖所有的情况覆盖所有的功能就能找出bug。由于第三次作业大家基本都没怎么优化,所以直接看输出结果很难看出正误,因此可以把每位被测者的输出结果赋上一个x值(比如x=1.1)比较不同被测者输出结果的值是否相等,若不相等显然是出现了问题。
3. 根据程序找bug
这种方法难度较大,主要原因是部分代码可读性较差,结构不清晰,等等。当然如果能看懂对方程序的话肯定是更容易从根源处找到bug。通过白盒测试,对复杂的类进行单元测试来寻找bug。
四、Applying Creational Pattern
1. 工厂模式
工厂模式(Factory Pattern)是Java中最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。因此,对于本次作业可以使用工厂模式来创建表达式,项,因子,我们只需定义一个创建对象的接口,让实现了该接口的子类自己决定实例化哪一个工厂类。在我们明确地计划不同条件下创建不同实例时,工厂模式将十分管用。
2. 抽象工厂
抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。超级工厂又称为其他工厂的工厂,在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。系统的产品有多于一个的产品族,而系统只消费其中某一族的产品时,可以使用抽象工厂作为所有工厂的抽象父类,这样我们就不用花费时间在选择接口上了。
五、总结与展望
1. 总结
4周时间过去了,OO也过去了第一单元,早就听说了OO的恐怖,如今也确实是体验了一番。总体来讲第一单元的学习还算满意,测试方面仍需加强,另外就是面向对象的思想还需不断的培养。第一单元其实主要还是java的入门,帮助我们更加熟悉java的使用。还有就是感觉今年的OO确实感觉要比往届好了不少,公测分占主要的情况下大体上保证了课程的公平,分ABC组互测也避免了一些悲惨的情况,总体来讲OO课在不断变好,在此感谢助教和老师的付出!
2. 展望
前路漫漫,道阻且长。后面还有多线程等等很难的知识和作业在等着我们,希望我们能继续努力,在本学期结束时能真正有很大的收获。
2019年北航OO第一次博客总结的更多相关文章
- OO第一次博客作业
OO第一次博客作业 一.三次作业的bug反省 1.自己发现别人的问题 (1)输入处理的问题,比如第一次作业,主要就是处理输入的字符串,然后有同学的正则表达式有问题,则对于一些错误输入就不能正确判断. ...
- oo 第一次博客作业
oo 第一次博客作业 早在大一就听说了oo的各种传奇故事,大二下学期终于也开始了我的oo之旅. 基于度量来分析自己的程序结构 第一次作业 类图分析 耦合度分析 可以看出在第一次作业中,我的耦合度非常高 ...
- OO第一次博客总结
虽然早在开学之前就已耳闻过OO这门课的威力,也在寒假自学了一些java的语法,但在真正面对OO这样的工程训练时才发现寒假所学的那点语法简直不值一提,也深刻的感受到在这个过程中自己的提升确实很快,毕竟d ...
- OO第一次博客作业--第一单元总结
OO第一单元总结 面向对象设计与构造的第一单元,对“面向对象”的概念还根本不理解不熟悉,只觉得需要“分模块”,但不知道怎么分,分多少模块,怎么根据需要的模块的功能建立类.学习的进度又太慢,根本跟不上出 ...
- OO第一次博客
过去的三周里我们完成了表达式求导的程序设计与构造.表达式求导程序,大致思路是实现一个表达式类,支持表达式的输入.求导运算和输出功能.可能的话,还可以增加表达式的化简方法,从而得到更高质量的输出结果.总 ...
- OO第一次博客作业总结反思
使用了masteruml插件来生成类图和metrics插件分析代码 第一次作业 1.UML类图 >在第一次作业中,使用了两个类,代码中有没有使用的变量与函数,为平衡两个类的内容,我将输出函数放在 ...
- 始入OO课程的殿堂,初识面向对象的奥妙——OO第一次博客总结
当我满怀期待叩开OO的大门,却发现宝藏藏在层层阻难之后 第一次作业 1.度量分析 >关于第一次作业的metrics图分析没有出现标红的McCabe Cyclomatic Complexity或者 ...
- OO第一次博客作业(第一单元总结)
Q:菜是绿的,鸡是黄的,那菜鸡是什么颜色的? A:红的,强测全WA了,能不红么. 菜不菜的问题先不说了,认真研究一下这次的题目,以及WA的原因吧. 程序结构简析 三次实验的核心结构都是差不多 第一次的 ...
- [BUAA OO]第一次博客作业
第一次作业 第一次进行面向对象的编程,不论是针对数据设计类还是对方法进行合适的归于不同类中,都不是很熟悉.所写出来的程序还是面向过程+有函数的类(虽然现在很大程度上感觉起来也是这样).索性作业难度并不 ...
随机推荐
- 解决Docker时区与主机时区不一致的问题
在Dockerfile里面增加以下红色的部分 FROM hub.chinacloud.com/common/jdk:8MAINTAINER xxx@chinacloud.com.cn RUN mkdi ...
- python操作数据库-数据表
数据表: 数据类型: 帮助的三种形式: 在cmd中输入: help 要帮助的主题词,或 ? 要帮助的主题词 或 \h 要帮助的主题词 . 数据表的创建: CREATE database IF NOT ...
- SpringMVC零碎笔记
在web.xml里可以配置webapp的默认首页,格式如下: <welcome-file-list> <welcome-file>index.html</welcome- ...
- python3中 for line1 in f1.readlines():,for line1 in f1:,循环读取一个文件夹
循环读取一个文件: fr.seek(0) fr.seek(0, 0) 概述 seek() 方法用于移动文件读取指针到指定位置. 语法 seek() 方法语法如下: fileObject.seek(of ...
- HDU1258 Sum It Up(DFS) 2016-07-24 14:32 57人阅读 评论(0) 收藏
Sum It Up Problem Description Given a specified total t and a list of n integers, find all distinct ...
- 磁盘配额(Quota)的应用与实践
1>什么是Quota 在Linux中,由于是多用户,多任务的环境,所以会有多用户共同使用一个硬盘空间的情况发生,如果其中有少数几个用户大量占用掉了硬盘空间的话,那肯定影响其他用户的使 ...
- wc.java
GitHub代码链接 1.项目相关要求 •基本功能列表: -c 统计文件中字符的个数 -w 统计文件中的词数 -l 统计文件中的行数 •拓展功能: -a 统计文件中代码行数.注释行数.空行 2 ...
- Android中设置分割线
设置分隔线的方法一: 在需要设置分隔线的布局文件中加入如下代码: <View android:layout_width="fill_parent" andr ...
- TFS Training for Kunlun bank (http://www.klb.cn/) 微软研发流程(ALM)管理培训会议(昆仑银行) 2016.09.21
银行一直是微软技术的伤心地,由于历史原因,微软技术和产品一直很难进入到银行业务的核心区域,但是微软今年来的进步不少,在开发工具和平台方面已经连续攻克了几个典型的金融企业,例如农业银行,中国人保等. 应 ...
- ASP.NET网页VS利用文件系统发布
1.点击发布 2.选择发布方式,这里选择文件系统,并选择发布的路径 3.配置相关参数 4.点击发布按钮 5.发布成功后文件夹下生成的文件 ..