做重构已经有一段时间了,在这段时间里面学了很多新东西,感觉自己的鸡窝做得越来越好了。这里,写下一些小Tips,记录下一些自己感觉很有意思的东西。
在上下机加完模式后,总感觉很诡异,我的上下机是加完模式后的,第一次这么做,还有点儿生疏,看了半天,才发现我上下机的逻辑居然在U层,如图:
三个类定义在了U层:
然后在下机的时候调用:
虽然能实现下机,但是具体的逻辑还是在U层里面,因为我是在U层定义在U层引用的。想完这个,深感自己对分层的理解才刚刚开始唉~
当自己不知道该把某块东西放在哪层的时候,这时候要问自己:这块代码是做什么用的,更加贴近哪一层?
在D层,我们抽象了SqlHelper,加入了实体-datatable转换类EntityConverter,虽然减少了连接数据库,读取数据库,关闭数据库和具体的表转换实体的细节问题,但是还是存在重复。例如,如每次执行sql语句,都要new个sqlHelper,不知不觉中,多了很多重复内容,以至于到了最后,又开始了copy的方法来new这些东西。其实,可以为要共享的过程或函数定义为shared或者更大方点儿,类也shared了,用的时候直接等就可以了。
在使用实体作为返回值的时候,有时回有这样的问题:比如,需要某个学生的充值信息,显示在窗体上的时候,要显示充值教师的信息(教师姓名,用户名,级别等。),学生本人的充值信息(金额,日期时间等。)。这两种信息我是写在两个实体中的。但是function只能返回一个实体,怎么办?
先想想我们一起是怎么办的:在上一版机房中,我们是直接选择两各表的,然后返回一个表集。利用datatable可以返回两个表的信息。但是现在返回的是实体,然后有人就想,回去改实体,在一个实体中,加入另一个实体的字段,虽然可以实现返回值的问题,但是不觉得冗余太多了吗?
我们还有很多很温柔的方法来实现。比如,将返回值隐含到参数里面。
例如:
下机完成之后,需要返回学生的上下机信息和学生部分基本信息,如图,参数和返回值正常写:
查完datatable之后,将一个datatable转换为两个实体集合:
既然参数可以隐含到参数里面,那么,是不是可以再隐含一下,将function直接写成sub? 童鞋们有兴趣可以试试,感觉这样去掉return其实挺好的,更加优化内存。
前段时间,有个小孩纸问完我datatable如何转换为实体集合的原理后,感慨万千:我的表字段和实体字段不对应呀,还得去修改实体字段,前面做好的程序都要改啦!其实,只要在select的时候,加上一个as,就可以解决这个字段不一致的问题,具体为啥自己实践下就明白了。例如:
在结账的时候,遇到个充值信息的显示问题,要显示如下数据:
但是充值信息的实体里面根本没有学号这个字段,学号这个字段只在基本信息里面才有,怎么办?当初想过利用隐含的返回值,返回两个实体集合,然后将两个实体集合都绑定到dataGridView上。但是没有实验了很久,没有实现。后来想到了一个比较损的办法,暂时解决了问题。
还是利用as进行转换,例如:
这样,临时把学号字段值存入实体的状态这个属性里面,在学号显示的时候,只需将dataPropertyName改为状态就ok了。
在很多地方,为了减少代码量,一个很好的方法就是设置默认值,只需在特殊的情况下指明一下。
目前感觉到设置默认值有两个好处:1,只需对特殊的地方进行处理,一般地方使用默认值就可以了;
2,如上图,在存储过程中为变量设置默认值,当查出为NULL时,系统 会 自动返回默认值0,不用再拿到程序中去转换了。
另外,这里还要补充下对Null值的处理:
很多时候,我们用AVG(),或者是SUM()进行计算,结果出来后确实null值,如果放到程序里面去处理,又觉得麻烦,这时候,我们也可以对这种情况使用。如图:利用ISNull函数,可以很好的解决这一问题。
对 数据库的时间的使用按照使用的位置可以分为两个地方,一个是在代码里:
在主窗体上显示时间的地方,要用一个timmer循环读取服务器中时间,然后显示。
另一个用到时间的地方就是在数据库里面:
强烈建议改掉以前用now()什么的读取本机时间,然后写回数据库的习惯。