概述:

  面向对象第一单元的作业是三次难度依次递增的多项式求导。第一次作业是仅包含带符号整数和幂函数的多项式求导,例如:-1+xˆ233-xˆ06;第二次是在前面的基础上增加了三角函数的求导,例如:-1+xˆ233*xˆ06-sin(x)*3*cos(x);第三次是增加了嵌套函数的求导,例如:(-1+xˆ233)*sin(xˆ2)ˆ06-cos(sin(x))*3。经过三次的求导训练,我学会了正则表达式的用法、Java内大数运算、对象与类、继承与多态、异常捕获、利用checkstyle检查并规范自己的代码等。

一、基于度量分析自己的程序结构

1、类图

  三次作业难度递增,类图的结构复杂度递增。前两次作业的项以及项求出来的导数具有相同的格式,故整体可划分为从输入串中读取项、求项的导数两大块内容。第三次作业复杂一些,采用了边读项边求导的方法。

1.1 第一次作业类图

  第一次作业结构相对简单,共分了CalculateDerivatives(计算每个项的导数)和ExtractCoefAndIndex(提取出每个项的指数和系数)两个类。写这次作业的代码时,刚开始接触java,代码中有很大部分还是过程式程序的写法,而且类的定义也不是很合理。总的来说,第一次作业并没有写出一个面向对象式程序应有的框架,很失败。

1.2 第二次作业类图

  第二次作业分成了Term项类和Expression表达式类(其中包含Main函数),通过这次作业学会了重写hashcode和equals等,但是代码中有很大的冗余,主要是自己构思的时候没有考虑清楚。而且,这次的代码只能为这次的作业服务,可扩展几乎为零。一旦更改要求,代码可能就要全部重写。

1.3 第三次作业类图

  第三次作业中涉及嵌套,结构相对复杂。分为常数类、三角函数类(包含嵌套)、乘类、加类、幂函数类五个类,通过接口返回每个类中的因子的数值和求导结果,整个代码运行过程中相当于从上到下生成一棵树,然后从下到上返回值和导数。这次的代码相比较前两次,整体可扩展性强,结构清晰。但是,我是用String类型返回的值和导数,这就使得项中的一些特点被抹去了,很难合并同类项、做相关的优化。所以,这次作业只能保证正确性,可优化性几乎为零。

2、利用MetricsReloaded插件的度量结果

 根据博客https://www.cnblogs.com/panxuchen/p/8689287.html安装并使用了该插件,运行结果如下:

2.1第一次作业度量结果

2.2第二次作业度量结果

2.3第三次作业度量结果

  ev(G)基本复杂度是用来衡量程序非结构化程度的,数值越高意味着非结构化程度高,难以模块化和维护。

  Iv(G)模块设计复杂度是用来衡量模块判定结构,即模块和其他模块的调用关系。数值越高意味着耦合度越高。

  v(G)是用来衡量一个模块判定结构的复杂程度,数值越大说明程序代码可能质量低且难于测试和维护。

  根据以上三个值判断,我的程序的高内聚低耦合度很差。主要原因是我的代码中类之间的层次没有分清,各个类之间的独立性较强,相互调用的少,没有区分好过程式程序和面向对象式程序。之后的实验中,我应该在代码的框架构思上多花些时间。

二、分析自己程序的bug

第一次作业的bug,主要是没有处理1*x的情况,之后将输出字符串单独处理,把1*消除。

第二次作业的bug,是因为程序的鲁棒性差,没有判断是否hasnextline(),导致程序在没有输入的情况下调用了String.nextline()函数,报错。

第三次作业的bug,是因为加括号的问题。有些地方必须要加括号,否则在特定的情况下会出错,例如sin(x+x)应该写成sin((x+x))。

bug的存在主要是因为设计的时候没有考虑到整体性,没有想好细节就开始写代码,导致debug之路漫长。

三、分析自己发现别人程序bug所采用的策略bug

1、自己构造比较全面的测试样例

  在第一次作业中,正确的输入和错误的输入的种类相对较少,可以实现全覆盖的测试;第二次作业兼容了第一次作业,故可以用第一次的测试程序来测第二次的代码,之后将第一次的测试样例中的 x 换成 cos(x) 或 sin(x) 继续测试;第三次的作业情况较多,很难全部覆盖的测试,可以根据自己的代码特点,每个分支写一个测试样例,保证覆盖测试自己代码的全部分支。

2、与同学交流

多多查看讨论区,学习下大佬们的思路和方法,避免踩大佬们踩过的坑;可以和周围同学多多交流,相互找bug。

3、写代码的时候保持脑子清醒

要在大脑十分清醒的情况下写代码,不然会出现很多的眼高手低的笔误,增加了debug时间。

三、Applying Creational Pattern

结合三次作业的要求,如果重构,我选择用工厂模式。

将输入串分解成一个一个的因子,之后利用工厂模式建立一个一个的因子类,每类中单独求导并返回求导结果。

四、总结与反思

  这三次作业给我的经验教训是,一定要先学,然后再写,不然很容易造轮子。想好整体的思路之后再动笔写代码,不要急于求成,不然,会像我的第一次作业一样写出很多冗余的代码。

OO_多项式求导_单元总结的更多相关文章

  1. OO_JAVA_表达式求导_单元总结

    OO_JAVA_表达式求导_单元总结 这里引用个链接,是我写的另一份博客,讲的是设计层面的问题,下面主要是对自己代码的单元总结. 程序分析 (1)基于度量来分析自己的程序结构 第一次作业 程序结构大致 ...

  2. OO第一单元总结-多项式求导

    OO第一单元总结-多项式求导 一.第一.第二次作业总结 因为前两次作业设计复杂度差别不大,因而放在这里统一总结. 基于度量分析程序结构: 前两次作业确实存在缺乏可拓展设计的构想,基本还是面向过程的思维 ...

  3. BUAA_OO Summary——多项式求导问题

    从C.DS.计组一路折磨过来, 几乎都在采用过程化.函数式的编程思想.初接触面向对象的项目开发,经过了三周的对多项式求导问题的迭代开发,经历了设计.coding.测评环节,算是对面向对象有了一定的认识 ...

  4. 多项式求导系列——OO Unit1分析和总结

    一.摘要 本文是BUAA OO课程Unit1在课程讲授.三次作业完成.自测和互测时发现的问题,以及倾听别人的思路分享所引起个人的一些思考的总结性博客.本文第二部分介绍三次作业的设计思路,主要以类图的形 ...

  5. OO第一单元总结——多项式求导

    第一次作业分析 1.程序结构分析 类图: 好吧,这一次基本上完全是在面向过程编程,没有看出来任何的面向对象的特性. 复杂度: 可以看到模块间的相互耦合度很高,PolyDerive方法的非结构化程度也不 ...

  6. OO第一单元总结__多项式求导问题

    作业一.含幂函数的简单多项式的求导 (1)基于度量的程序结构分析 1. 统计信息图: 2. 结构信息图: 3. 复杂度分析 基本复杂度(Essential Complexity (ev(G)).模块设 ...

  7. OO随笔之魔鬼的第一单元——多项式求导

    OO是个借助Java交我们面向对象的课,可是萌新们总是喜欢带着面向过程的脑子去写求导,然后就是各种一面(main)到底.各种方法杂糅,然后就是被hack的很惨. 第一次作业:萌新入门面向对象 题目分析 ...

  8. BUAA_OO_homworkone包含三角函数的多项式求导

    第一次作业 基于x的简单多项式相加求导 带符号整数 支持前导0的带符号整数,符号可省略,如: +02.-16>.19260817等. 幂函数 一般形式 由自变量x和指数组成,指数为一个带符号整数 ...

  9. BUAA-OO-第一单元表达式求导作业总结

    figure:first-child { margin-top: -20px; } #write ol, #write ul { position: relative; } img { max-wid ...

随机推荐

  1. @property的使用

    1.可以将某个函数变为属性 class Name(): @property def name(self): print('xiaoming') Name().name这里name已经可以当做属性来调用 ...

  2. (转)SQLServer_十步优化SQL Server中的数据访问一

    原文地址:http://tech.it168.com/a2009/1125/814/000000814758_all.shtml 第一步:应用正确的索引 我之所以先从索引谈起是因为采用正确的索引会使生 ...

  3. sql优化使用技巧

    1.LIMIT 语句分页查询是最常用的场景之一,但也通常也是最容易出问题的地方.比如对于下面简单的语句,一般 DBA 想到的办法是在 type, name, create_time 字段上加组合索引. ...

  4. js Base64 转化成图片格式

    function dataURLtoFile(dataurl, filename = 'file') { let arr = dataurl.split(',') let mime = arr[0]. ...

  5. eShopOnContainers 看微服务⑤:消息通信

    1.消息通信 传统的单体应用,组件间的调用都是使用代码级的方法函数.比如用户登录自动签到,增加积分.我们可以在登录函数调用积分模块的某个函数,为了解耦我们使用以来注入并放弃new Class()这种方 ...

  6. Linux 常用系统工作命令

    1.echo 用于输出字符串或者变量的值 2.date 显示及设置系统的时间和日期,格式为 “date [选项][+指定格式]”,输入以“+”号开头的参数,及可按照指定格式输出 date命令参数及作用 ...

  7. Delphi全局热键的注册

    1.在窗启动时创建ATOM;(aatom:ATOM;定义在private中) then begin aatom:=GlobalAddAtom('ZWXhotKey'); end; ) then beg ...

  8. Linux命令:let

    语法 let  expr [expr ...] 说明 计算c的算术表达式.详细说明请参考<Bash参考指南-6.5 shell算术运算>

  9. 如何在Python中调用Matlab

    检查您的系统是否具有受支持的 Python 版本和 MATLAB R2014b 或更新版本.要检查您的系统上是否已安装 Python,请在操作系统提示符下运行 Python. 1)打开Prompt,输 ...

  10. nvm管理node版本

    一.介绍与作用 不同的项目中可能使用的node版本不同,对于维护多个版本的node就是一件麻烦事了,而nvm就可以很方便的管理不同的node版本, 可以在不同的node版本间切换使用.NVM资源(针对 ...