写这篇文章的初衷是为了记录我在修复项目中一个复杂业务组件中的bug而引起其他依赖这个组件的功能无法使用的过程中,对使用、维护复杂业务组件的一些思考

原文地址

Bug发生原因

我所在的项目组中, 有一个类似树状文件管理的需求

对于这样的需求,当时我设计一个基础的UI组件treeListView用来实现基础的树状UI, 同时在其基础上实现了explorer业务组件来实现具体的业务逻辑。

由于是树状的视图,所以在当时设计数据结构时也采用树作为数据结构。为了能够方便的查找树中的数据,我按照系统的文件管理给所有的数据添加了一个path属性。

但是在实现的时候没有考虑到同级目录下面可能同时存在同名的文件夹和文件这种情况,假设文件夹folder下面同时存在名为file的文件和文件夹,这个时候会造成它们的路径相同,在查找的时候无法区分这两个数据。修复的方法是在文件夹的路径后面增加/

这样修复后,由于在我们的项目中有许多的地方直接使用path来来做判读,例如有的地方直接分割path来获取当前数据的名称或者其父元素的名称(虽然有更好的方式获取这些数据,但是开发过程中可能为了省事直接这样获取),或者在新建文件、文件夹时自己手动的拼写path

当我按照上面的方式修复bug时,就必须同时修改这个依赖path的函数操作,当项目中的代码太多时就可能出现遗漏的情况,给代码的维护带来很大的困扰。

为什么会出现这么多的问题?

问题出现了之后就应该去反思为什么造成现在这样的局面。诚然有一部分的原因是我们在开发过程中经常会图方便而随意的使用数据,但是根本的原因是在对一个复杂的业务组件调用过程中,没有一个方便、有效的操作造成的。换句话说就是对于组件依赖的数据没有一个有效的操作造成的。

组件的正确依赖于数据的正确,而在开发的过程中不同的开发人员有着不同的风格的数据处理方式。 一旦数据结构出现了错误或者发生了修改,就会导致组件出现意想不到问题。

如何解决这样的问题?

对于业务组件, 我们是可以总结出对这个业务组件的调用的使用情况,例如本文中的explorer组件主要有以下几种情况:

  1. 新建文件夹、文件
  2. 删除文件夹、文件
  3. 修改文件夹、文件
  4. 根据路径查找文件夹、文件
  5. 根据路径查找父文件夹

对于这些操作,在组件的编写过程中我们可以同时编写对应的辅助函数,

explorer组件我就编写下面的辅助函数

return {
  // 修改属性操作
  modify: modify,
  // 重命名操作
  rename: rename,
  // 新建操作
  create: create,
  // 复制操作
  copy: copy,
  // 移动操作
  move: move,
  // 删除操作
  remove: remove,

  // 搜索树中符合要求的数据
  searchTree: searchTree,
  // 根据路径返回在树种的索引
  searchByPath: searchByPath,
  // 根据路径获取数据
  getDataByPath: getDataByPath,
  // 根据路径获取父目录的数据
  getParentDataByPath: getParentDataByPath,
  // 根据路径获取父目录路径
  getParentPath: getParentPath
  // 初始化数据中的path
  addSourcePath: addSourcePath,
  
  // 判断是否存在同名数据(用于新建时同名判断)
  hasSameName: hasSameName
};

这样对于调用者来说,只要使用组件提供的辅助函数就可以方便的使用组件;对于组件的维护者来说,只要保证辅助函数的正确性,就可以保证组件在被调用的过程的正确,方便组件的维护。

总的来说,就是在编写这样复杂的业务组件,我们应该同时编写相关的辅助函数来方便组件的调用者来使用。而我们在开发中也应当避免写出上文中那样对数据直接进行操作的代码,这会导致业务的正确依赖于组件的内部数据相耦合,使组件难以维护。


LLeo小浩
133 声望2 粉丝

前端菜鸟