十二月 2006 - 随笔

做报表统计的几点收获

在刚刚过去的做报表的一段时间里,一个人拥有一个工程,一个人静静的思考面对的问题,一个人细细的雕琢自己的代码。出现问题,思考或者寻求帮助,发现思路,然后推翻原有代码结构体系,在重构中又有新的认识,形成新的思路,然后又开始整理代码……这种经历,以及这种经历带来的感觉真的很好。而在之中形成的认识收获,对于自己以后的编程无疑具有很好的指导意义。

下面我就谈谈我的一些收获,主要谈如下几点:

1 程序按层次进行组织;

2 封装和重用;

3 异常处理;

4 重构。

 

程序按层次进行组织

最底层的函数实现具体的统计细节,完成如统计判断,累加等操作。上层的函数按照调度逻辑实现对底层函数的调用,然后继续被上一层代码调用。越往上层越远离具体实现细节,越抽象,越往下层越接近细节。在每一个函数中的语句都处于同一个层次。如何判断一个函数中的所有语句是同一个层次呢?看上一条语句和下一条语句和本身是否平级,是否存在“观念”上的先后关系。一个函数只干一件事,实现一个逻辑,函数里的语句恰好反映了实现这个逻辑的先后顺序。

程序按层次进行组织的好处在于一旦某个时候在某个地方的调度逻辑发生改变,只需在对应的函数进行变更。比如这次统计报表的实现,由于我之前是按照层次进行代码组织的,后来,yongxu说某个地方逻辑不是那样子的,结果我只用了一点点时间就调整过来了,因为我只需要对负责实现这个细节的函数进行修改就行了,没有出现“牵一发而动全身”的情况。并且由于分层组织,使得逻辑清晰,代码可维护性好。

我们很容易犯的一个错误就是过早的陷入细节。是的,细节的实现使得我们可以很快地看到效果,而且有时实现细节的过程似乎有点激动人心的,毕竟完成细节意味着我们把任务完成了大半。无可否认,这样做会让我们很快的把心放下来,但是常常是这样作,使得实现细节和调度逻辑混合,细节掩盖住调度逻辑,之后我们又不愿花点精力把细节抽取出来,还原调度逻辑,最终层次变得混乱,后期维护变得困难。

 

封装和重用

如果说生活中的事情我们将很多任务交给同一个人好比将很多鸡蛋放在同一个篮子中,一旦篮子坏了,所有鸡蛋就打碎了,风险很大;那么,对于编程,则确实需要我们将所有鸡蛋尽可能的放在同一个篮子中,一旦需求变更了,只要换个篮子就行了。这就是代码重用的好处。

比如:在统计的逻辑实现过程中,把一些公共的逻辑抽取出来,封装在帮助类中;把不确定的过于细的逻辑通过函数“丢”出来,实现对变化的隔离,等等。这里附带提一下,并且对于实现同一功能的函数,我们可能需要暴露不同的接口形式,以前我通过函数重载的方式来解决,但是在每个重载的函数里都给与了具体的实现。实际上,我们可以将所有实现细节放在一个大而全的函数中,其它函数只是传递的参数数量或者参数值不一样,以后维护只要维护这个大而全函数就可以了。这个做法是组长clyin告诉我的,实际上,这也是微软的做法。

 

异常处理

一个人拥有一个工程,意味着要一个人控制程序执行过程中可能发生的异常。特别是这个工程是通过Windows Service来调度的,一旦发生异常就使得服务停止,这无疑不是我们所希望看到的,必须将所有异常“扼杀”在工程里面:让异常刚一冒芽,就“掐”掉。然而,我的代码中又要利用NOD来访问数据库,也就是说我要调用第三方的代码。

为此,对于每一次调用第三方代码,我都要对结果进行校验,是否有为Null的。对于获取出来的结果,比如一个学生,每一次利用其子对象的属性,我要判断其是否为Null,防止抛出“操作对象没有引用实例”的异常,等等,总之,调用别人的代码,别人的代码对我来说,就是“黑盒”。同时,我自己的上层代码对自己的下层代码的调用同样当作是“黑盒”来处理。尽可能确保每一步都能够“正常”进行,一切纳入正常轨道,而不会发生“异常”。

 

重构

当我有了一个新的思路之后,我就迫不及待的将代码实现。这样带来的好处是对瞬间灵感的把握,然而,同时,代码的质量也降低了。命名的规范,代码的层次,参数没有校验等等在编码之初都显得毫无章法,于是,不得不开始重构。然而,在重构中,最大的收获倒不是将函数名字从“Get”改为“Set”,不是从一个方法内部提取出一个独立的方法,而是在重构中,对自己之前思路的再认识,往往在这个过程中,又激发了新的想法,发现新的问题,得到新的思路。很享受这种感觉,在不断的重构过程中,体会着自己思维的变化,对问题的认识一步步深刻,解决方案的一步步改善,这种感觉真的很好。

 

发布于 由 ozheric0 篇评论

“报表统计,舍我其谁?!”

前段时间,一直在做报表统计,很有收获。这是我第一次编写报表统计相关的程序,从最初的惶恐,到过程中的点点揪心,到最后完成工作的舒心,一路走来,别有一番滋味在心头。有句话说:“痛快”何以为“快”?全因“痛”字在先。痛过之后的快乐,岂是“欢快”所能比?如是这般,这回,我算是“痛快”了一回。从这篇文章题目你也可看出,我现在该有多“痛快”。是的,我就这样,当我感觉自己在某个方面有那么点收获,我就无法抑制内心的兴奋,变得狂妄,一点也不知道收敛。

 “独乐乐,与众乐乐,孰乐?”这份痛快,不敢独享,遂拿出自己做报表统计的一些体会,与大家分享。在这里,我也得感谢qwLiang,没有他的指导参谋,我可能跌倒在了起跑线。感谢dcdingclyin,他们给与了我充分的信任,并给了我足够的时间来思考碰到的问题,没有这么长时间一点一点的“磨”,我不会有这么多的认识和体会,不会思考那么多。

 

    首先说明,我的统计不是利用sql语句实现的,而是在程序中实现的。我要统计的报表都是二维报表,解决方案的大致思路是把二维报表看作是一个矩阵,然后通过遍历查询出来的结果集,对每一条记录分析应该对二维报表的哪一行,哪一列进行累加操作。这样做的好处在于我们不再需要对每个单元格建立一条查询语句,由于得到哪一行,哪一列都是变量表示,使得我们的代码具有很大的伸缩性,我们不用维护那么多条sql语句。好吧,下面我将详细介绍我的问题和解决方案。下面的这个报表是我这次进行报表统计过程中的一个,我作了一些精简,去掉了几行,目的是要清晰的说明问题了。

     1 要统计的报表举例:

学生变动统计                                                               单位:人

上学年初报表在校学生数

      

       

本学年初报表在校学生数

退

死亡

非正常

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

 

01

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

其中

02

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

少数民族

03

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

说明: 1、“招生”、“在校生”数应与表3-1相关数据对应相等。 2、本表列关系为(16=1+2-7);(2)=(3)++(6);(7)=(8)+(9+(10)+(11)+(12)+(14)+15)。

   2 解决方案

 

   具体的展现形式先不用管,我们要有这样一个观念,统计是负责把数据库中的满足我们条件的数据查找出来,然后进行累加,报表展示是页面的展示形式,这两者是可以分离开来的。故此,我们可以把它根据关系数据库规范化理论第一范式,把这个报表“规范化”,变成一个矩阵。具体来说就是下面这样一个形式:

 

上学年初报表在校学生数

增加总计

 

招生

复学

转入

其他

减少总计

退

死亡总计

非正常死亡

转出

其他

本学年初报表在校学生数

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16