面向对象-第一单元总结

一、对面向对象的理解

  有位同学给java的面向对象做了一个形象生动的类比,我觉得很有道理,大概按我的理解如下:

    • 结构的形成
      看图之前,我们要先明白,世界上是先有了实体,才有了一步步抽象至以上的体系结构,当然也未必是自底向上逐步抽象,也许在最初的认识体系中,只有故宫里的植物C、植物、和存在,或许迎客松A和蒹葭B都是植物的对象,在之后的认识中逐步向上抽象出生物,向下细分为树和草等等。
      但无论如何,所有的抽象类都是我们从实体中归纳总结出的,不是凭空产生的。   
      在真实的程序设计中或许我们也是如此,也即先有简单的层次,生物-植物-ABC,随后逐步细化功能迭代开发。
    • 类与接口

      抽象类与接口十分相像,一般用借口能实现的东西我们都可以通过抽象类来实现,但从结构上看来,抽象类是分类,接口是功能,就像图中的光合作用是接口,树和草是类,树和草描述的是实体的构成模式,光合作用描述的是他们所具有的功能,还是有很大区别的。

    • 抽象类
      抽象类并不是不可以指代一个对象,仅仅是不能实例化一个对象,实例化的对象可以通过抽象类来指代,就像故宫里的那颗植物可能是一棵树,但是同样可以通过植物来指代。

二、实践与设计思路

  至今为止面向对象开课以来已历五周,共实现了三次作业,都是表达式求导,功能逐步增加,对于面向对象理解的逐步加深也对我的程序结构产生了不同的影响,以下作出归纳:

  

  • HomeWork1

  题目描述:多项式求导,多项式仅由带符号整数、x的一次函数与x的幂函数构成。

  对于面向对象一知半解,以为一个类用于当作函数主路口,另一个类用于实现功能就已经半只脚踩入面向对象的大门了;实际上不过是“include”一个头文件的过程式设计而已。当然功能实现没有问题,只不过到了HomeWork2需要重写了。且结构上维护困难。

  由于Derivation类仅仅实现函数的入口功能,连格式判断都放在Poltnomia类中,所以直接的结果就是该类的体量巨大,度量数据超标都是此类的问题。

  另一方面,由于正则表达式判断时(getIn方法)使用的是多个if-else-return结构,结构化程度ev(G)与循环复杂度v(G)都很大。但调试与理解起来并不是很令人费解,当然这是个人非数据的感觉。

  总而言之,第一次作业的实现并没有明白面向对象程序的编写方式,用完全过程式的思想去编写程序,唯一觉的有利于编程的是java巨大方便的类库~

  • HomeWork2

  题目描述:多项式求导,多项式由带符号整数、x的一次函数、x的幂函数与x的sin、cos函数构成。

  题目一出来,就发现第一次的作业白写了,于是有感为了让第三次的作业好写一些,尽力的修修补补得到了如下的结构。因为写的时候并没有题头的所述的那般理解清楚,所以很多结构上有冗余,第一次使用继承、抽象类,还没有很深的理解,于是勉强有如下的结构,但自认为结构上或不甚清晰,类内部的实现有些混乱。主要体现在AddFunction和MultyFunction的组成,使用了Function的Array组成其数据结构,但一方面这debug不方便,另一方面优化时不容易。

  首先从类图看,Term是函数入口,Function作为求导函数的顶层抽象类,直接继承它的是加和函数、乘积函数和基本函数,基本函数也是抽象类,其有幂函数、X函数、常数函数和sin、cos函数五个子类。从结构实现上,基本实现了我所预想的结构。但静态分析仍有问题。

  如上图,由于方法过长,右边的方法仅给出了超标部分的截图。

  从类的结构来看,Term和Function的平均复杂度很高,这是由于Term沿用了正则表达式判断输入格式的方法,仍然是if-else-return加大了复杂度,Function是因为兼具了工厂函数的功能,并不仅仅作为抽象类而存在,我想这应该需要避免,功能和数据结构的定义最好分开。

  从方法复杂度看两个match方法都是使用了正则表达式if-else-return的结构,加大了复杂度。而Multy中的getout主要原因是用多个if结构来优化造成的结果。

  类间的相互依赖关系如上,因为MultyFunction和AddFunction中的函数项组成采用了顶层抽象类型,即内部类型结构表述与思考有些混乱,为了避免出现错误,就使用了最大的描述类型。这点在第三次作业做了些改变。

  • HomeWork3

  题目描述:多项式求导,多项式由带符号整数、x的一次函数、x的幂函数与x的sin、cos函数构成,允许sin、cos内部嵌套表达式及其他函数,允许幂函数底数使用x的函数项或表达式。

  由于第二次作业的正确决策,第三次就不需要重新考虑结构,仅仅调整了幂函数的位置,并对结构内部进行了一些修改与优化,包括精确化函数类型,加和函数明确为乘积函数组成,乘积函数明确为幂函数组成,考虑嵌套,幂函数、三角函数内部使用加和函数类型。正则表达式判断格式直接使用了第二次的代码,基本没什么修改。另一方面,分离了工厂函数和顶层抽象类,使得结构更加清晰。

  类图结构上并未有太大变化,入口函数在Derive类。

  Derive类中包含了match正则表达式匹配方法,if-else-return结构使复杂度增大。当然,关于这个问题,可以通过递归分部解决,在递归部分我也加入了判断,或许程序中有冗余,但是并没有太在意去改变。CreatFunction类是生成函数,因为需要括号匹配,这一点或许可以通过递归逐层解决,但是在这次作业中,我使用的是过程式匹配,这或许有违面向对象的初衷。

  由于结构的更改,Power作为优化中极为重要的一步,通过if来进行判断。复杂度略有增加。

  另一方面,因为一开始写的时候并没有了解到instanceof可以判断函数具体到那个子类。所以有isBaseOr。。。来判断嵌套函数是否是常数函数或者表达式函数。

 

  通过清晰化结构一定程度降低了类间的依赖度。

  • 总结

  三次作业的第一次作业完全按面向过程式编程,维护程度比较低下,程序测试分数也较低。第二次作业,第一次用了面向对象的思路编写程序,虽然测试分数更低了。。。当然或许第一次作业没有为第二次作业留下出了bug数据以为的好处。第三次作业很大程度上复用了第二次作业的代码,得到了不错的成绩,也算是一种鼓励吧~体会到了复用的好处。

三、bug分析

  • 第一、二次作业
  1. 公测
  2. 互测
      关于前两次互测,被发现的bug都是FormatWrong,正则表达式考虑不完全所造成的后果……因为通过正则表达式判别,或许与设计结构关联不大,一二次的结果相似。
  3. hack策略
      通过自己程序的bug和复用曾经自己被hack的bug来测试别人的bug。效果不错。也有可能是因为身处C组的缘故。
      查看别人的源代码,有针对的hack,成功率很高,但是效率比较低,看别人代码大多数时候真的很累。
  • 第三次作业
  1. 公测
  2. 互测
      因为不测WrongFormat!!!(如果测可能还是有问题)所以被hack的主要内容是关于常数项的判断,与前两次类似的地方在于,都出现在方法复杂度高的地方。
  3. hack策略
      通过自己程序的bug和复用曾经自己被hack的bug来测试别人的bug。
      查看别人的源代码,有针对的hack,未成功过。。。或许是水平不够。

四、总结与Applying Creational Pattern

  大概收获最大的并不是某次作业,而是最后的一次同学分享。就如题头说的,面向对象的建构不是一蹴而就的,或许我们最先反应过来的模型都是简单的相对不抽象也不细化,得到的体系与结构也仅仅是不完善的。

  表达式求导,在第二次采用面向对象方法设计的时候,确实在码代码之前进行了深入的思考,想清楚得得到一个清晰的架构,最后的结果是得到了一个初步的模型,但对于内部细节并没有很完善,具体的分析前文提到了。通过反思与和同学的交流,在第三次作业重写了部分方法,重新整理了数据结构,相对的跟清晰的获得了体系。当然任然存在在不完善的地方,通过反思与思考仍然可以更进一步的优化~

原文地址:https://www.cnblogs.com/YeSiyuan/p/10597658.html

时间: 2024-11-05 20:32:40

面向对象-第一单元总结的相关文章

面向对象第一单元总结

目录 一.任务需求 二.实现方案 多项式数据结构的设计 多项式解析与WRONG FROMAT判断 表达式求导 表达式简化 三.基于OO度量的程序分析 四.程序bug分析 五.对象创建模式 六.对比和心得体会 第一单元通过三次迭代的表达式求导任务建立对面向对象程序的初步认识,并熟悉面向对象的思维和编程方法. 一.任务需求 三次作业的需求如下: 第一次作业:求解简单多项式导函数 第二次作业:求解包含简单幂函数和简单正余弦函数的表达式的导函数 第三次作业:求解包含简单幂函数和可嵌套因子的正余弦函数的表

OO_2019_第一单元总结——表达式求导

一.基于度量的程序结构分析 首先给出Complexity metrics中参数的含义: ev(G):基本复杂度是用来衡量程序非结构化程度的,非结构成分降低了程序的质量,增加了代码的维护难度,使程序难于理解.因此,基本复杂度高意味着非结构化程度高,难以模块化和维护. Iv(G):模块设计复杂度是用来衡量模块判定结构,即模块和其他模块的调用关系.软件模块设计复杂度高意味模块耦合度高,这将导致模块难于隔离.维护和复用.模块设计复杂度是从模块流程图中移去那些不包含调用子模块的判定和循环结构后得出的圈复杂

第一单元总结

登录vnc ip:172.25.254.250:7 ############虚拟机相关操作############## [[email protected] Desktop]$ rht-vmctl start desktop ###开启 Starting desktop. [[email protected] Desktop]$ rht-vmctl view desktop##显示 [[email protected] Desktop]$ rht-vmctl stop desktop##正常关闭

第一单元练习题

<<<第一单元练习题>>> 1.用student用户登陆系统图形界面 2.打开一个bash 3.修改student的密码,把密码更新成"T3st1ngtlme"(主机字母和数字) psaawad student 4.显示当前系统时间 date 5.显示当前系统时间,显示格式为:"小时:分钟:秒 AM/PM"(AM/PM为上下午标识) date +%X%p 6.显示"/usr/bin/clean-binary-files&

运维第一单元练习题

<<<第一单元练习题>>> 1.用student用户登陆系统图形界面 点击student user - 输入password 2.打开一个bash 右键--open in terminal application--utilities--terminal gnome-terminal 3.修改student的密码,把密码更新成"T3st1ngtlme"(主机字母和数字) passwd student -更改密码T3st1ngtlme 4.显示当前系统

第一单元. &nbsp; &nbsp; &nbsp; &nbsp; Linux 系统登录及部分基础命令

第一单元 1. 用student用户登陆系统图形界面 [[email protected] Desktop]$ rht-vmctl start desktop  ####打开虚拟机#### Starting desktop.                                      #####虚拟机开启中### [[email protected] Desktop]$ rht-vmctl view desktop    #####显示desktop#### [[email pro

.C#认证考试试题汇编:第一单元:1,11 第二单元:1,11

第一单元1,11 好久没用异或都快忘了,就让我们一起来了解哈啥子事异或 说的这个,就不经意让我想起书上的几种交换值得方法了 我这儿说的交换的方法是,不使用第三个变量来交换,而是两个 实现条件是C a=100,b=10;第一种 缺点可能会如果超出范围溢出a=a+b; a=110,b=10b=a-b; b=100,a=110a=a-b; a=-10,b=100b=100,a=10;第二种 缺点可能会如果超出范围溢出a=a*b;a=1000,b=10b=a/b;b=100,a=1000a=a/b;a=

linux基础学习 第一单元练习

第一单元练习题 1.用student用户登陆系统图形界面 2.打开一个bash 3.修改student的密码,把密码更新成"T3st1ngtlme"(主机字母和数字) 4.显示当前系统时间 5.显示当前系统时间,显示格式为:"小时:分钟:秒 AM/PM"(AM/PM为上下午标识) 6.显示"/usr/bin/clean-binary-files"的文件类型 7.统计"/usr/bin/clean-binary-files"的文

初级学习Linux第一单元

##############虚拟机控制############### [[email protected] Desktop]$ rht-vmctl start desktop          ##打开虚拟机desktop Starting desktop. [[email protected] Desktop]$ rht-vmctl view desktop          ##显示虚拟机desktop [[email protected] Desktop]$ rht-vmctl reset