面向对象第一单元总结

一、对面向对象的理解

  有位同学给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/10607982.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249314.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

理解HTML语义化

1、什么是HTML语义化&#xff1f; <基本上都是围绕着几个主要的标签&#xff0c;像标题&#xff08;H1~H6&#xff09;、列表&#xff08;li&#xff09;、强调&#xff08;strong em&#xff09;等等> 根据内容的结构化&#xff08;内容语义化&#xff09;&#xff0c;…

maven上传命令

mvn deploy:deploy-file -DgroupIdcom.oracle -DartifactIdojdbc8 -Dversion12.2.0.1 -Dpackagingjar -DfileC:\Users\Admin\Desktop\ojdbc8.jar -Durlhttp://116.247.107.83:8081/repository/maven-releases/ -DrepositoryIdmy-nexus-releases

cocos2dx 开启控制台

打开 SimulatorWin.cpp 把这句启用&#xff1a; #define SIMULATOR_WITH_CONSOLE_AND_MENU 1 这句本来因为#define隐藏了转载于:https://www.cnblogs.com/mingfuqishi/p/9774301.html

网页编排规则

所谓大纲&#xff0c;简单来说就是文档中各内容区块的结构编排。可以分为显式编排和隐式编排2种方式。 显式编排&#xff1a;明确使用section元素创建文档结构&#xff0c;在每个内容区块内使用标题 隐式编排&#xff1a;不明确使用section等元素&#xff0c;根据页面中所书写的…

基本动态规划题集

观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径&#xff0c;使路径经过数字的和最大。每一步可以从当前点走到左下方的点也可以到达右下方的点。 在上面的样例中,从13到8到26到15到24的路径产生了最大的和86。 【输入】 第一个行包含R(1≤ R≤1000)&…

springboot项目间接口调用实现:RestTemplate

https://blog.csdn.net/zhanglf02/article/details/89842372

python入门学习的第三天

step 1 时间 Python有两个模块&#xff0c;time和calendar&#xff0c;它们可以用于处理时间和日期 首先 import time 导入时间模块 然后 print time.time() 这个叫时间戳&#xff0c;它是从1970年1月1日午夜到现在时刻的秒数 print time.localtime(time.time()) print time.st…

JavaScript事件详解

JavaScript与HTML之间的交互是通过事件来实现的。事件&#xff0c;就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以用侦听器来预订事件&#xff0c;以便事件发生的时候执行相应的代码。 事件流 事件流描述了从页面中接收事件的顺序&#xff0c;包括事件冒泡和事件捕获。…

JavaScript基础01

JavaScript查漏补缺 JavaScript有几种数据类型&#xff1f; 0. String(字符串) 1. Number(数值) 2. Boolean(布尔) 3. Null(空值) 4. Undefined(未定义) 5. Object(对象)前 5 种是基本类型 Null类型和Undefined类型的定义和区别&#xff1f; Null类型的值只有一个(null)&#…

.Net Core应用框架Util介绍(五)

上篇简要介绍了Util在Angular Ts方面的封装情况&#xff0c;本文介绍Angular封装的另一个部分&#xff0c;即Html的封装。 标准组件与业务组件 对于管理后台这样的表单系统&#xff0c;你通常会使用Angular Material或Ng-Zorro这样的UI组件库&#xff0c;它们提供了标准化的U…

SpringBoot中处理的转发与重定向

https://blog.csdn.net/yubin1285570923/article/details/83796003

scrapy爬虫系列之三--爬取图片保存到本地

功能点&#xff1a;如何爬取图片&#xff0c;并保存到本地 爬取网站&#xff1a;斗鱼主播 完整代码&#xff1a;https://files.cnblogs.com/files/bookwed/Douyu.zip 主要代码&#xff1a; douyu.py import scrapy import json from Douyu.items import DouyuItemclass DouyuSp…

glup server 报错 Task function must be specified

解决方案 今天像往常一样&#xff0c;编写文章&#xff0c;并使用gulp bulid压缩代码&#xff0c;但是一运行&#xff1a;gulp build 就出现了这个错误&#xff1a;AssertionError: Task function must be specified。 gulp项目需要全局安装gulp和项目内安装gulp&#xff0c;…

mybatis Example 使用方法

一、mapper接口中的方法解析 mapper接口中的函数及方法 方法 功能说明 int countByExample(UserExample example) thorws SQLException 按条件计数 int deleteByPrimaryKey(Integer id) thorws SQLException 按主键删除 int deleteByExample(UserExample example) thorws SQLE…

gulp + browsersync实现页面自动刷新

写习惯了vue&#xff0c;特别喜欢vue的自动刷新功能&#xff0c;于是琢磨在node中如何自动刷新&#xff0c;使用过nodemon&#xff0c; 但是感觉效果差点&#xff0c;看到网上有gulp livereload的方案和gulp browsersync的方案&#xff0c;但都是褒贬不一&#xff0c;先简单记…

[JZOJ5836] Sequence

Problem 题目链接 Solution 吼题啊吼题&#xff01; 首先如何求本质不同的子序列个数就是 \(f[val[i]]1\sum\limits_{j1}^k f[j]\) 其中 \(f[i]\) 表示的是以 \(i\) 结尾的子序列个数 先把原数列的不同子序列个数求出来&#xff0c;然后观察一下这个转移&#xff0c;贪心的发现…

numpy和pandas的基础索引切片

Numpy的索引切片 索引 In [72]: arr np.array([[[1,1,1],[2,2,2]],[[3,3,3],[4,4,4]]]) In [73]: arr Out[73]: array([[[1, 1, 1],[2, 2, 2]],[[3, 3, 3],[4, 4, 4]]])In [74]: arr.nd…

mybatis的Example[Criteria]的使用

https://blog.csdn.net/u014756578/article/details/86490052

Thunar 右键菜单等自定义

Thunar 右键菜单等自定义 可以使用图形界面或者直接编辑配置文件&#xff0c;二者是等价的。 图形界面&#xff1a; 以给“zip&#xff0c;rar&#xff0c;7z”等文件添加“在此位置使用unar解压缩”的右键菜单为例&#xff1a;&#xff08;unar可以很好地处理编码问题&#xf…

JavaScript设计模式(二)之单例模式

一、单例模式的定义 单例就是保证一个类只有一个实例&#xff0c;实现的方法一般是先判断实例存在与否&#xff0c;如果存在直接返回&#xff0c;如果不存在就创建后再返回&#xff0c;这就确保了一个类只有一个实例对象。在JavaScript里&#xff0c;单例作为一个命名空间的提…