软件构造学习记录(承)

  那么上一篇作为开篇之后,回头总结了一下四次实验的内容。再结合复习的部分,打完底稿以后,终于要完成这篇新的博客了。

先磨磨刀

  首先是一个小的总结:那么在我看来,四个实验可以划分为两个部分,理由如下:
  实验一(基础Java编程和测试实践)和实验二(抽象数据结构和面向对象编程实践)归属于基础部分,在这两次的实验中,在代码质量方面强调的是代码在构建时和运行时的正确性、代码在构建时的可读性、代码在运行时的健壮性;在思想指导方面,强调的是从面向过程编程到面向对象编程的一个转换。

问:为什么课程不选择C++而是Java?
答:我也想问这个问题,因为大一接触的是C,虽然语法上C++和Java类似,但是C++又被称为“C加加减减”,和之前的知识有所关联,而碍于个人能力不足,本学期的软件构造课程几乎被我当作了Java编程学习了。
  但是,静心一想后,我给出了如下的回答:相比C++,Java是一门更加彻底的面向对象编程的语言,当下主流的软件产品,Java的分量也不小,Java易于上手而且更为安全,适合新人(尤其是Eclipse这样的方便、亲和的IDE更是解决了我很多的问题);而C++,它继承自C,即方便实现面向过程编程也对面向对象编程进行了扩展,它的指针使得它更加适合进行系统一级的编写和引擎一类的软件的开发,总得来说更加复杂,对于本门课程是更加不合意的。

  接下来是实验三(面向可复用性和可维护性编程实践)和实验四(Debug、异常处理和防御性编程实践)。它们算是更贴近商品软件的一些要求(只能说,比起之前的单元性问题,它们强调的点在于上一篇中的软件的外部质量因素,更加贴近用户的需要,而实际上我在完成这两次实验时,一塌糊涂XD)。

问:设计模式意义何在?
答:坦白地说,我没学会,只了解了其中一部分设计模式的理论模型,对于抽象这门技术活,我训练得不足。
  但在这里给出一个万金油式的我的想法:
  总的来说,设计模式是前辈们在工作和实验中总结出来的经验性抽象模型,这些模型的伟大之处在于,就我的知识水平而言,至今没有超脱这些模型的新模型出现。而这些模型的现实意义在于,学习者能够根据需求,选择一个合适的模式,去设计那些需要的代码块(比如,当我们在未来可能需要为代码加入新的具有共性的模块时,就像工厂生产一般,我们可以采用可维护性的工厂方法模式来编写代码,通过添加新的“工厂”和“产品”来完成任务,而不是面对耦合度过高的代码头疼XD)。

所谓“承”

  这一篇设计到的是实验一和实验二的内容,就课程安排而言,它们更加贴近之前的学习(也是面向过程到面向对象的有个转换)。那么接下来,就回顾一下我关于这两个实验的学习过程。

实验一

  三个问题:幻方鉴定、海龟画图下函数编写、社交网络。三个问题都是独立的单元,其中:幻方鉴定是典型的面向过程编程,旨在学习语法;海龟画图下部分函数,用来帮助我们熟悉函数的调用(最后一小题是凸包的计算,如果使用之前编写好的函数,那么会事半功成),以及测试用例的书写;社交网络的内容则是对面向对象编程的一个引入,这部分的内容在实验二中再次出现,并做了一个对比(课程设计好的优秀抽象模型和我的糟糕对象模型的对比XD,使用一个设计好的对象模型真的更加方便,实验二也接着这个说明了实验三的重要性)。
  幻方鉴定。我的方法很普通,百度定义,构造函数去硬算各种要求,总的结果为真说明是幻方。
  海龟画图下函数。给定了函数的功能,使用已经设计好的转向和步进函数,那么很轻松能够设计出画出的图形。在此过程中涉及到一个计算转角的函数,那么引入数学函数库,检查完使用的arctan函数得到与0°的角度,之后再分类计算应该顺时针转的角度。最后一部分是计算凸包,百度定义,我的思路是,只要一直进行转角最小的过程,那么如果下一个最小转角点已经在经历过的点集合的中,那么说明,这个集合中已经包含凸包了;最后再进行一个筛,从重复的那个点开始,再对集合中的元素进行一边凸包的寻找,那么新集合的点就是原来的凸包。
  另外一提,正式到这个问题,我才正式接触Java的测试功能,借用JUnit库,通过划分等价类和边缘检查,然后使用测试用例来检测代码的正确性。优点:省时、根据合理的方法选择的测试用例能够保证安全性能。缺点:课程中要求事先编写测试用例,这对习惯了事后检查的我来说就没那么友好了,我有时不能决定一个函数的最终功能,经常在编写中改变策略,导致了测试用例应该的表现形式的不确定。
  社交网络。自行设计抽象数据类型完成任务。我在实验中没有能够很好地使用面向对象编程的方法,所以任务的完成更像是把两个类当成了大型的带方法的结构体来完成任务。也没有能够很好地理解题意,不带思考地选择了佛洛依德算法来计算了最小路径,复杂化了问题。

实验二

  同样,三个问题:诗意漫行、社交网络、棋类游戏。前两个问题联系紧密,其中:诗意漫行需要我们先完成给定规约的泛型的两个实现类,并且选择一种实现类来完成诗意漫行的内容;社交网络的要求和实验一中一致,这里体现了好的ADT和差的ADT的一个对比,在实验二中我们需要使用诗意漫行中的图类来完成;棋类游戏,自行设计ADT,完成面向对象编程,实现两个棋类游戏(我失败了,虽然完成了代码,但是还是面向过程的形态,没有做到向面向对象编程的转变XD)。
  诗意漫行。(原谅我糟糕的语言水平,只能这么翻译了。)那么这个任务引入了新的东西,规约、表示不变量、不变性检查。对于一个方法,它的输入和输出约束了方法,写明功能的注释就是方法的规约,方法必须按照规约来严格书写,因为规约是供使用者来查询的工具,我们必须先做到“诚信”,才能希望使用者正确使用方法。而我的理解中,表示不变量是类中属性不会变动的那一部分,它们由于实际问题的原因,不应该针对某一方法发生变化。而不变性检查则是为了确保在方法执行后,表示不变量保持了“不变”。
  这里带来了我最讨厌的内容,规约的书写和类规范的书写(大概普通程序员会很恨两件事:写注释和不写注释的程序员XD至少我是这样矛盾的)。而如果给定了规约,那么这题完成起来的难度并不高,按照规约,我也轻松地完成了本题。
  社交网络。使用上一题中的图泛型,这一次很轻松地就构筑了一个简单的社交网络,而计算最小路径使用的方法则是:由于人和人之间总是一个单位的,那么只需要按照圆心去一层一层地发散,就可以找到最小的路径了,这个过程可以使用上一题写出的寻找下一个点的集合来实现。比起实验一中的弗洛伊德算法,这次的实现十分简洁明了,可见一个设计优良的ADT是如何使得工作事半功成的。
  棋类游戏。又是一个自行设计,那么我在这里简单贴出我实验报告的一部分来反映我在这题的学习情况吧。

   按照要求设计了Game、Player、Board、Piece、Position、Action,另外有Go和Chess两个Game的子类用来执行不同游戏的内容。
  Game有元素Board和Player,Player拥有Action,Board拥有Piece,Piece拥有Position。而Action起到一个记录并复现记录的作用,它的一切变量都是final的,不供外界改变,各变量也具备不可变性。
  Game通过解释输入来互动,由于这是我第一次尝试OOP方式的ADT编程,我完成的程度相当不好,虽说是在写ADT模块,但是几乎所有的方法都仅存在于内部之间的相互调用,并且代码的重复率也令人吃惊。因此没能够很好完成相关属性的检查,以下只能谈谈我的思路:
  主程序与外界交互获得游戏名,游戏者等相关信息,生成一局游戏,根据游戏名来初始化Game的Chess子类或者Go子类,这决定了游戏的规则。在Game中循环调用GameCheck来解释不断输入的语句,并根据事先设定好的分类方法完成相应的操作。在此过程中Player对象的工作只有添加动作,检查完GameCheck的情况之后,Action来解释上一轮发生的行为,对Board进行对应的调整,从而达到外部对内部的一个正常交互。

  可以看出,我虽然努力向面向对象编程的形式上工作,但是还没能够逃出面向过程编程的框架,我想这也是我今后学习需要注重的一部分。此外,我也没能够实现一个图形的界面(这在实验要求中被高度推荐,这也反映了我学习能力的不足,十分遗憾)。

小小总结

  实验一中学习了Java的基本语法,初步接触了面向对象编程和测试用例的编写。而实验二中则是通过使用和设计ADT来完成面向对象编程的内容,课程方向已经逐渐转向对于外部因素的控制了,也就是转向商品软件的模式(虽然我水平有限并且只能制造学术垃圾XD,但是我感觉这里就是课程内容诱导我们向商品软件构造的一个中间节点,因此第二次博客也就到此结束)。
  那么,真正编写一个软件的时候我们又会遇到怎样的问题呢?这得等实验三和实验四的内容才能知晓了。

以上,致礼

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值