本文首发于稀土掘金。该平台的作者 逐光而行 也是本人。
前言(个人以往的经验体会+本次思想学习的重要性)
截至目前,还没有完全由我自己独立完成的项目(或者说我觉得自己的水平还非常有限,弄的东西还不能称为项目,最多只能算个勉强能跑起来的小Demo),但是已经有一些维护或者魔改别人的项目的经验。
项目的质量参差不齐。以某个项目为例,最初发现自己能把该项目成功跑起来的时候,我是很开心的,再粗略看了看代码,哇,大佬写得好专业、好复杂!但是真正开始改的时候,这就变成了另一个故事。
随着对代码的进一步分析,发现某些看着很复杂高深的代码其实一言难尽。比如:“耦合度高”:一段代码明明可以封装成一个类或方法单独放在一个位置,它却偏偏要在每一处都出现一遍,想修改一个小小的地方就得把相关的东西全都改一遍。什么?你说让我重构一下,把它整理整理然后拎出来就好了?兄弟,事情远没有这么简单。原代码其他部分写得似乎跟那些重复的代码紧密相关,想要把某部分单独抽起来,几乎所有相关联的类的大部分代码都得重写一遍。本来在我还有时间的时候,我还是很想完成这个光荣而艰巨的任务的,直到我遇到了以下两件事,让我彻底放弃了这个想法。项目和我,有一个能跑就行。屎山代码不是我区区小人物能动得了的。
我想对某个模块进行迁移,结果改好了之后测试了一下,发现里面有个功能已无法使用,经过debug,才发现有个参数的值变成了null。为什么会变成null?原因是代码原作者对数据进行了一些不必要且有隐患的绑定:同一个静态数据,不是直接在后端传参,而是先传给前端,之后又把前端的数据解析给后端另一块。那我模块迁移了,这个传输链就断掉了。这又引出了一个新问题:代码之间真的不应该有一些多余的关联。自此,其他模块我也不敢随便乱动了,谁知道又有什么潜在的bug被触发?
后来我又想,我改不了,增加点东西总是可以的吧?事实证明我还是太天真了。原本我想给某个页面增加一个按钮和相应功能,但是发现原代码层层关联、跳转混乱、我花了好几个小时,才搞明白原有的按钮的逻辑设计是怎么回事,而按它原来的这种写法,我这个新加上去的按钮也不是独立添加就可以的。(具体涉及到项目细节,我也不方便透露太多,但是!!!同样的功能,如果按常规写法,真的应该是独立分开的啊!)那次以后我突然深刻地领悟到,一个可以被不断维护的代码,至少应该做到对拓展开放。
有了以上惨痛的亲身经历,当我看到以下论述的时候,大呼妙哉!感觉每一条都戳中了我!见贤思齐焉,见不贤而内自省也,希望我写出来的代码能给别人带来好的感受。
代码分层结构设计
- 框架应该是独立的,不要依赖于某些软件的库。
这些库可以作为一种拓展工具,但是不能让整个系统都受它限制。
就比如,如果一些核心组件用的是外部库,万一外部库整个都迁移或者宣布停止维护了,那这整个项目不就也跟着瘫痪了吗?外部库可以用来锦上添花,但绝对不能将身家性命都托付上去。
- 在没有UI、数据库、服务器这些外部组件的情况下,也能经得起测试。
我的理解是:得保证一些基础的东西也没有问题,然后才考虑UI、数据库之类是否有bug。同时,基础的东西和UI、数据库之类的应该是分开的,这使得bug定位会容易一些。
- 界面是独立的,不要和系统逻辑有太大关联。
见我前言提到的例子。我觉得界面就是界面,它就做好自己的本职工作,展现美观的页面,给用户带来良好、丝滑的操作体验,不要插手多余的事情。
- 数据库是可迁移的,不要过度依赖于特定数据库,而应把它作为一种抽象的概念。
比如这个项目现在用MySQL,我换成Oracle也应该可以,我换成OpenGauss也能行。换一个类型的数据库所进行的改动应该尽可能少,不能到处都得改一遍。
- 不要依赖于外部代理。
共勉!