Web应用开发实用编程指导(二)—大道至简

mengsun 2014-07-24

        大道至简——老子·《道德经》

        代码是我们的敌人——Jeff Atwood ·《高效程序员的修炼》

        硅谷的大牛Jeff Atwood说过一句言简意赅的箴言:代码是我们的敌人。其实代码不光是程序员的敌人,它还是一切与项目有关的人的敌人。多一行代码就意味着:多一行代码需要调试,多一行代码需要阅读,多一行代码需要测试,多一行代码可能发生错误!这就像“蝴蝶效应”,随着项目时间和人员的累积,一个项目将会变得越发臃肿而且错误频发,而一个项目越臃肿和错误频发就要投入越多的人力和时间进行维护,这样就形成了一个恶性循环。著名的IT顾问Andy Hunter曾在他的《程序员的修炼之道》里面指出:一个rot的项目通常都是从一些小的模块开始腐烂的,即所谓的“破窗效应”。而为了避免一个项目过早地走向衰败,我们可以从根本下手,那就是减少代码的数量!

        减少代码的数量,从哪儿做起呢,我觉得最有必要的就是从SQL语句开始下刀!

        很多应用系统的开发人员喜欢把大量的逻辑写到sql语句里面,比如下面的SQL,包含了日期类型转换和一个case语句:

        select convert(date,’yyyy-mm-dd’),case A when 1 then … else end from …

        逻辑控制是程序的强项,SQL(标准化查询语言)是检索和更新数据的语言。程序是面向对象的,SQL对于应用系统来说不过是一句扁平的字符串。面向对象的程序语言显然有更强的逻辑处理能力,有更加强大的扩展性和可读性。SQL函数有很多都是非标准化的,不同的数据库之间函数的写法完全不同,从这一点看SQL的移植性也大大不如程序。而且不恰当的sql函数使用可能令数据库索引失效而发生全表扫描,比如把函数放在where语句里面。

        试想上面的语句的查询结果如果要先后应用在两个页面上,A页面要只显示年-月-日,B页面要显示年-月-日时分秒,难道你要再写一条SQL语句?另外,嵌套在sql里面的case之类的逻辑语句如果较多,将给阅读SQL带来不方便,如果非要在sql语句里面进行这样的处理,应该考虑能否把这部分语句用循环的方式在程序里面生成。

        写复杂的sql不是一件牛B的事情而是为项目增加拖累,在应用开发时尤其如此。如果是做数据分析数据挖掘之类的事情,那就另当别论。

        减少代码的数量,第二件可以做的事情,减少冗余的方法和SQL语句

        这件事对于那些几乎不写设计文档的项目组来说似乎有困难,也许他们可以用代码生成器或自定义框架之类的办法来减少这样的问题。当然如果有代码评审或结对编程之类的措施就更棒了。Jeff Atwood就曾在他的博客里面大加赞赏这两种工作方法,并一度指出这样的方法可以降低60%的BUG发生率!

        有如下一段方法签名:

        selectProductByA(String A);//给XX君调用

        selectProductByAB(String A ,String B);//给某A页面用

        selectProductByABC….(String A,String B,String C…..StringN);//给C页面用

        不要小看这种现象,这种现象几乎在我经历的每个项目里面都发生,而且在大项目中这种问题可谓数不胜数。很多人似乎都不屑于在写代码前先去看一看那些已经有的接口,这实在是个不懂团队合作的坏习惯。这种浪费型的写法带来的后果是项目中类爆炸、接口爆炸,BUG反复出现,也许一个小小的修改要涉及到四五个不同的类和方法。这种写法一开始就应该用一个对象参数来包含各种参数的调用。类似的浪费写法还有一些无谓的重复sql,比如按a属性查询写一个sql,按ab属性查又写一个sql。方法的参数定义应该简略,当然最好的传参方式就是对象。不要觉得这种方式是大材小用,在需求扩展的过程中你必将体会到对象传参的精彩妙用,而且对象(领域模型)也是连接三层架构的一条重要纽带。

        减少代码的数量,第三件可以做的事是把正确的代码写在正确的地方!

        一个项目的规模通常会随着需求的变化而变化,因此三层架构仍不失是项目中可采用的万全之策。那么如何在这三层架构中找到代码的位置呢,首先你必须做到第一点——简化SQL!

        一般来说Dao层类是和数据库表对应的,那么我们可以按照返回的数据集结果来决定把我们的SQL放在哪个Dao里面。

        在很多简单的小型系统中,业务逻辑基本上就等于数据查询的逻辑,因此服务层的作用被大大弱化了——基本成了控制层和Dao层之间的“传话筒”,或者在一些spring框架中做事务控制之用。但是,当SQL语句被简化后,一部分业务逻辑就被往上“推”到了服务层,我们会发现原来“打酱油”的服务层慢慢变得有事可做了,服务层里面可以做各种判断,鉴权,运算以及复杂数据结构的整合,也就是把各个Dao里面查出来的数据做各种转换,达到符合控制层输出的目的。

        控制层做的事情主要是对页面的数据进行接收和校验,并且做一些简单的数据转化,比如截取、过滤这样的事情,并决定最终视图的走向。如果你有一个自定义的el函数库之类的东西,在页面上做些数据的转化也未尝不可。

        合理地安排代码的位置,可以提高代码的复用性,这让我们更轻松地适应需求的变化!

        我国伟大的思想家老子在数千年前就发现了“大道至简”的道理。简单意味着强大,简单意味着轻松,简单也意味着更低的成本。所以我们应该着力于如何把复杂的事情变简单!Make it easy!

相关推荐