代码改变世界

如何让自己的javascript代码具有可维护性?

2013-04-21 20:26  MoltBoy  阅读(930)  评论(0编辑  收藏  举报

  为雅安祈福!!愿好人一生平安!!

  现在的Web程序不再是简简单单文字和图片的排版输出,稍微大点的网站都有成千上万行javascript代码,执行各种复杂的功能提供用户不同的交互体验。往往当你进入一家企业,很多情况并不是让你开发新的web程序,而是让你基于原有的成果开展工作,如果代码不具备可维护性,那么此项工作就会变得相当难以进展。

  那么什么是可维护性呢?它具有什么特征呢?

  - 易读易懂 —— 不需要原作者解释,就能直接读懂源代码,并能轻松基于这些源码开展下一步工作;

  - 可扩展 —— 代码的构架能适应未来功能的扩展;

  - 数据灵活性 —— 改动代码中的某些数据,只需修改少量代码而无需重写所有的代码就能适应;

  - 可追踪 —— 网站某些地方出了问题,能轻松通过代码直接定位到问题所在位置,并能解决问题,避免重复发生。

  拥有以上特征的代码可以说具备了一定的可维护性,那我们该如何去做,才能让自己的代码拥有以上的特性呢?

  良好的编程习惯以及好的文本文件格式化习惯可以增加代码的可读性,这方面最常见的问题在于代码的缩进和排版。通常情况,许多人使用制表符号来缩进,但是不同的文本编辑器会显示不同的效果,所以一般推荐使用4个空格来代替,当然你也可以使用其他数量的空格。

  让代码阅读起来容易理解,最直接简单的办法就是增加注释。那么是不是可以通篇的添加注释,好让别人轻松读懂呢?其实,只需要在以下一些地方进行注释就足够了,例如:

  1、函数和方法:此部分的注释应该包括:函数和方法的目的和用于完成任务涉及到的算法,参数的类型和意义,返回值的一些情况。

  2、大量代码:完成单一功能的大量代码段需要一个注释,用来描述其完成的任务。

  3、特殊算法:当你使用独特的方法或算法来完成某些任务时,需要较为详细的注释其过程,以及优势和特点。

  4、hack部分:增加注释避免被后面的开发者误删除。

  其次,在变量和函数名方面也需要做到语义化,最好别使用毫无意义的名字,避免“foo”、“bar"等不良的使用习惯。变量名尽可能使用相关的名词,如:person、cat、car等。函数名最好使用动词,如:getName()、getAge(),返回布尔值的函数一般以is开头:isFunciton()。在可理解的前提下,可以适当的缩写单词,不要过多地担心名字够长的问题,到后期部署的时候可以通过压缩处理的方式来解决。

  由于javascript的变量是松散类型,特别容易忘记之前声明的变量的数据类型。但是通过合适的方式可以一定程度上缓解这个问题。这里提供三种方式来表明变量的数据类型。

  ①、对变量进行对应类型的初始化赋值。例如,将来保存布尔类型的变量初始化为true或者false,对象类型的变量初始化为null等。

  ②、使用匈牙利标记法来命名,也就是在变量名前面加一个或者多个字符来表示数据类型。个人比较推荐这种方式,比较直观,只是在易于理解方面确实值得斟酌。下面几种类型的变量使用匈牙利标记法命名:bFound-布尔、iCount-整数、sName-字符串、oPerson-对象、fNumber-浮点数。

  ③、在变量后面添加注释,表明变量的类型。var found;  //Boolean

  每种方式都有自己的优缺点,好比第一种方式声明的变量,无法在函数参数中使用,第一种和第三种都不够直观,需要在声明的地方查找。

  容易阅读和理解的代码如同艺术品一般具有可欣赏性,浅显的道理,美好的东西需要通过分享来展现。做到易读易懂还远远达不到可维护性的目标,让代码可维护还需做到松散的耦合性,通俗点就是某部分不要过度依赖代码的另外一部分,跟做人的道理一样,过度依赖只会让你变得非常被动,正所谓靠山山会倒,靠人人会跑,靠父母父母也会老。

  最为典型的紧耦合:一个对象直接引用另外一个对象,这样的情况下,此对象完全被彼对象牵着鼻子走。紧密耦合的代码会变得非常难以维护,企业往往会选择重写代码。

  因为web应用涉及的技术,有许多种情况让它变得耦合紧密。因而注意以下几种情况:

  HTML和javascript代码紧密耦合。因为它们天生就是一对怨男怨女,难以分割,所以让它们变得紧耦合的方式就有很多种,例如:直接在html中写javascript,或者在javascript中添加html。从技术上来说,这两种情况都没有什么问题,但是维护人员肯定就会直骂娘了。理想情况下,HTML和javascript应该完全分离,并且通过外部文件和DOM附加行为来添加js,而动态添加html尽可能用在页面中直接添加html并隐藏的方式来代替,然后等页面渲染好之后,再通过用javascript来显示该段标记,而不是动态地生成它。另外还有一种方式,进行ajax请求并获取更多要显示的HTML,这个方式可以让同一的渲染层(PHP、JSP、Ruby等)来输出标记,而不是直接在javascript中。

  将HTML和javascript解耦可以在调试过程中节省时间,更加容易确定错误的来源。

  CSS和javascript代码紧密耦合。前面说了HTML和javascript是怨男怨女,那么CSS就是小妾(负责HTML的打扮),javascript是原配,可以支配着小妾的活动来打扮HTML。如果CSS和javascript紧密耦合,维护人员可不只是骂爹娘了,估计骂得冒泡十八层。但是,现在的web应用上经常需要动态修改CSS,可以通过动态修改样式类来缓解此类问题的存在。通过只修改元素的CSS类(修改类名或增加类名等),就可以让大部分样式信息严格保留在CSS中。

  另外,在IE8或低于IE8版本中,在css中通过表达式嵌入javascript代码。强烈建议不要使用此类表达式,因为它们不但不能跨浏览器兼容,而且还会引入javascript和CSS直接的紧密耦合。在这里,郑重提醒:各层次间必须有清晰地划分,做到层次间不混合。

  应用逻辑和事件处理程序紧密耦合。 事件处理程序中含有应用逻辑代码,会让业务逻辑部分难以调试。较好的办法就是将应用逻辑部分从事件处理程序中分离出来,事件处理程序应该从事件对象中获取相关的信息,并把这些信息传送到应用逻辑的处理方法中。如此,应用逻辑部分可以更轻松地进行单元测试或者自动化测试。

  业务逻辑和事件处理程序之间松散耦合性的三条原则:

  ◆ 勿将event对象传给其他方法,只传递来自event对象的数据;

  ◆ 任何可以在应用层处理的动作都不应在事件处理程序中进行;

  ◆ 事件处理程序处理事件,然后将处理结果交给应用逻辑。

  最后,还有一些关于让代码可维护的编程习惯:

  ◇ 不要随意修改不是你创建或负责的对象,包括其属性和方法,更不可对原生类型和对象任意妄为。遇到此类问题,变通的解决办法:创建自定义类型,继承需要进行修改的类型,然后可以对自定义的类型添加额外的功能;或者创建包含所需功能的新对象,并用它与相关对象进行交互;

  ◇ 尽可能避免使用全局量。推荐使用单一的全局对象和命名空间解决此类需求。全局对象作为容器,里面可以定义其他对象来包含全局量。整个YUI库都包裹在YAHOO容器中,例如:YAHOO.util.Dom; YAHOO.util.Event; 等。这中间可能要多一些代码量,但是相比可维护性而言,这点代价简直微不足道。

  ◇ 使用常量。javascript中并没有常量的概念,但是它真的很有用。它可以将数据从应用逻辑中分离出来,并且修改数据不会引入新的错误。特别在是多次使用的数据上,以及用户界面字符串、URLs和任意可能修改的值。另外,常量一般使用对象属性来声明,并且严格使用全部大写字母表示。使用常量相当于将经常修改的值进行集中的管理,避免多处修改。

  ◇ 类型检查。javascript本身不会自动类型检查,因而需要手动检查。检测某个值是否为空,勿将它直接与null比较,因为常常会由于检测类型不充分而导致错误。通常使用以下方式进行类型检查:①、值为引用类型,使用instanceof检测其构造函数;②、值为基本类型,使用typeof检测其类型;

  ◇捕获异常抛出错误,重点关注函数和可能导致函数执行失败的因素,并提供详尽的错误信息,让使用者及时追踪到错误。