收获:编码之前必须的思考是逃不掉的,而且这一步是磨刀不误砍柴工,而且会加速以后的步骤
分析:
首要重要的事情是:需要完成的功能,理清逻辑关系。我们要随机产生一定要求的算式,并且计算出算式的值。
其次的事就是那个差点没读懂题的要求:重复题目的判断,为了实现检验重复,最让我心烦的就是那个奇奇怪怪的判定条件,而且还有括号的参与,一开始头脑是完全晕的。然后才在同学的提醒下想到了以前学过如何用二叉树来表示一棵树,这个方法最好的地方就是去掉了之前困扰我很烦的括号,所以同学(外援的重要型就凸显出来了)
最后就是心中就要开始有一颗大树,心中就要开始编写代码,开始规划整个的布局了。看了搭档的代码才反应过来的操作数的结点和操作符的结点是同一种类,毕竟是同一棵树的葫芦娃都应该整整齐齐
编代码:
说实在的,虽说在假期自学了点c++的基础知识,而且自己动手写了...写了20-行的代码试了试自己学没有学懂,但是对于这种较大的工程,较认真的作业这还是第一次。和队友在一起编代码的过程中,一次一次地被队友嫌弃自己写的代码太麻烦,封装很不好,调用地很不爽。当然我是一个懒人,写完了不想再动它,但是还是得有理有据的拒绝队友,故意的问了问凭什么要封装起来?这样子不也行吗?然后往往也就一句话:这样子封装好了调用者才不用关心函数具体是怎么实现的,如果多次被调用在修改的时候是无敌的方便主要还不会错。对,队友说了这样的话不少于7、8次了,每次都还是觉得封装起来才对,想象一下想要修改一点点内容结果全工程到处找就觉得可怕。所以,慢慢的知道了,封装就是为了集成,就是让使用者放心,不管我们怎么做的只管用就好。脑子里突然就换位思考了,就像最基础的函数调用者,也就是我们,在使用别人家的函数工具时才不会去关心是怎么写,只管拿来用就好;那么要让顾客如此的放心,就该写好每一个封装。
类的成员变量一般不会很开放的公布示人,所以大都是通过调用函数来实现的,这一点虽然有些烦,一个个两三行的超短小函数总觉得不爽,但是想想这样也就将自己的变量隐藏起来,稍想改动一下也很容易,关键是别人就不知道里面是怎么回事,感觉这种神秘感很刺激。整块代码全是用调用各种函数实现的。
不管是整个工程还是一个功能较为复杂的函数都是迭代式、增量式地发展的。为了写好我负责的那个后序遍历二叉树的过程中生成表达式并且计算出表达式的值,外带如果生成的二叉树非法就还要稍稍修改此树的部分节点,或者标记其为一棵废树。
最开始先是计算表达式的值,因为没来括号,二叉树的遍历过程正好就是计算过程(简直就是lucky),主要是那时候随机产生结点的函数还没有写好,所以就先将求表达式放在哪儿(这一步涉及修改树->产生结点)。当然就想着正常的套路利用返回值来轻松方便的递归求值。写完了求值,然后开写求表达式,然后就尬住了,因为,求这两个东西都要用函数返回值才方便,于是乎撞车了,那么为了二者兼容还好之前即商量好了将最终的结果用一个结构体装表达式和结果,所以就用它了。因为修改函数返回值要改的地方太多了,于是想偷懒直接在参数表上面动手脚,然而效果很不好,更加的麻烦,来来回回修改了4、5次函数的参数表和返回值类型,那天晚上可谓是心累呀,主要是这个函数实现的功能确实有点太多了,是工程中核心函数之一,所以复杂些还是很正常的。感觉整个过程很曲折,如果下次有打好腹稿,心中有树,有一个较为明确的思路,就不会在这上面纠结了。
每次给函数增加功能的时候,记住!记住!记住!要反复检查一下功能之间的衔接,是否冲突!不然bug玩死你!
入口检验很重要,讲道理每一个函数都应该有一个入口检验,即使是一个确切永远不会发生的错误也得有入口检验!内部函数要加入口检验,提供给外部的函数更加要加入口检验!
测试检查:
为了在自己测试中完全找到bug,我们都不管使用者是不是小学生,真当一群猴子在闭着眼睛敲函数。将所有的参数情况全部测试了一遍,几百种情况挨个挨个来,最后好事发现了一个很关键又不是很重要的bug,因为使用者是小学生所以应该不会让参数太大,以至于计算过程中的数值超过了一个long long 可以承受的范围,起初还想着不用管,但是谁知道对面的使用是什么物种,还是将这个bug很重视的用异常处理解决了一下下(头一回用异常处理,好紧张的,虽然几乎不会触发这个异常)。
对接:
UI组和我们core组的关系就像是,程序员和顾客的关系,我们在决定接口的时候就在想,应该怎么办才能让我们的用户(UI组)用得方便,开心,仔细琢磨了一阵对比了2、3个想法还是提供一个唯一的接口函数是最简洁方便的了。只要我们的内部处理好了,写好API文档应该不会有大问题,提供函数的好处就是,封装了设置参数的过程,同样是让UI组远离核心细节,看不见内部的实施过程,就像开开心心地调用系统函数一样快乐!
最后:
有一组不同于其他组用的文件的形式,而是用读取内存的形式,还好由于之前对于对接时不清楚UI组的接受方式,所以做好了两手准备,原型就是读取内存的内核,外包装是自己输出文件两者一前一后完全不冲突,这让我们对接时很方便的修改成了文件、内存二者兼容的模式。这让我知道了,即使不清楚目标的方向,那么就要把所有可能的结果都要兼顾着做出来,要有前瞻性的眼光,顾大局。