屎山公理:重构屎山与造轮子感想一二 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
meeken
V2EX    随想

屎山公理:重构屎山与造轮子感想一二

  •  1
     
  •   meeken 2019-09-14 17:21:36 +08:00 6472 次点击
    这是一个创建于 2293 天前的主题,其中的信息可能已经有所发展或是发生改变。

    屎山公理:重构屎山与造轮子感想一二

    shishan

    前些日子看了 V2EX 一张帖子,内容如下:真想给自己一耳光,几年前居然是这么烂的水平,目前修改得快要怀疑人生了,把一堆屎山不仅要啃完还要耐心品尝、细嚼慢咽的茫然感觉谁懂。

    ###类《三体》的基层程序员维护复杂项目的两条公理

    • 跑起来是开发的第一要义
    • 需求和功能常常变动,但工期与计划学习周期几乎不变

    你看,屎山不就出来了吗。

    ###关于屎山

    抛开理论不谈,代码写的烂,维护困难,就会想重构,这是猿之常情。

    在我刚接手公司的核心项目时,最直观的感受便是:看不懂。我是写前端的,我们的项目是 Vue 写的,Vue 在设计之初不适合用来写大型项目,我想原因之一是项目变重以后,状态管理单靠组件通信会十分困难。这个项目大改是 17 年启动的,那时候可没有什么 Vuex。

    当然还有很多代码写着写着变得很迷,经常出现一个页面近千行代码,本该可复用的组件却有奇奇怪怪的依赖,想把他们拆分开来的念头在一次次报错中打消了,心里油然而生一种想法:刚才我在吃屎,现在我是在切开吃屎。

    ###接手代码后

    一个敏捷开发程序员经常会接手别人的代码,维护,next。这就要求代码必须像积木一样灵活,换言之,你维护的那一块哪怕就此回滚或者删去,也不会对代码整体造成影响。

    道理谁不懂呢,但事实上现在几乎国内的项目都是由一坨坨黏糊糊的屎构成的屎山。有时候我是掏粪男孩,有时候我是拉屎的,这种气急败坏的感想真的是在一次次维护祖传项目时得出的。

    ###关于用轮子与造轮子

    有个场景如下:你是员工小明,某天 leader 突然给了一个任务:为当前的项目加入 foo 功能,要求是 bar,限期多长时间完成。同时,leader 温馨提示:Github 上有个项目能嫖来改一改就能用哦。

    但是,当你把那个嫖来改一改就能用的项目拉下来,可能会出现以下几种情况:

    1. 它真的嫖来改改就能用,遂嫖之
    2. 它能跑,但是有很多部分需要改动,且使用的技术栈与你项目一致
    3. 它能跑,但是有很多部分需要改动,且与你使用的技术栈不一致
    4. 它是屎山,你都不知道怎么让它跑

    我们知道,由于工期设限,要想在简短的时间里达成任务,复用轮子是一个屡试不爽的方法(适用于情况 1,2 )。但如果这个备胎是破的,或者跟你的项目完全不适配,或者因为自己技术力不足无法驾驭(适用于情况 3,4 ),比较之下,是不是造个轮子会更方便呢?

    我认为是这样,因为:

    1. 你的新轮子可能不是屎山了,因为一个项目之处,谁都不想把它写成屎的
    2. 你的新轮子可能会写成屎,但是是自己的屎闻着更香

    无论是想法 1 或 2,要是下定决心了,你很可能会去造一个轮子,至少我会。

    但是,参考屎山公理,倘若需求是不断变更的(这也是程序员工作时常常碰到的情况),而设计稿 / 项目计划没有提及,又该怎么办?

    ###如何少写屎山

    耦合性与内聚性是模块独立性的两个定性标准,将软件系统划分模块时,尽量做到高内聚低耦合,提高模块的独立性,为设计高质量的软件结构奠定基础。

    对外低耦合,对内高内聚

    有个例子很容易明白:

    一个程序有 50 个函数,这个程序执行得非常好;然而一旦你修改其中一个函数,其他 49 个函数都需要做修改,这就是高耦合的后果。一旦你理解了它,你编写概要设计的时候设计类或者模块自然会考虑到“高内聚,低耦合”。

    • 耦合、内聚的评估标准是强度,耦合越弱越好,内聚越强越好;
    • 所谓过度指的是由于错误理解导致的效果相反的设计;
    • 耦合指的模块之间的关系,最弱的耦合设计是通过一个主控模块来协调 n 个模块之间的运作。还是举一个我举过的例子:客户要求在界面上增加一个字段,你的项目要修改几个地方呢?如果你只要修改项目文档,那么你的开发构架就是最低强度的耦合,而这种设计 成熟的开发团队都已经做到了,他们使用开发工具通过项目模型驱动数据库和各层次的代码,而不是直接修改那些代码; 内聚指的是模块内部的功能,最强的内聚就是功能单一到不能拆分,也就是原子化;
    • 所以强内聚和弱耦合是相辅相成的,一个良好的设计是由若干个强内聚模块以弱耦合的方式组装起来的。

    引用自: https://leader.js.cool/#/experience/design/architecture

    这位大佬的书非常精辟,如果你是一个渴望提升自己或者改善生活的底层程序员,建议可以看一下,不要钱。

    (声明:不是广告!不是广告!不是广告!)

    ##总结

    此文是我在一次重构屎山时有感而发,几乎都是抱怨,亦或者是无能怒气。希望大家在今后能够少写屎山,为下一个维护代码的人多着想一下。 如果有啥有用的建议,欢迎分享 QAQ。


    -EOF-

    10 条回复    2019-09-16 09:30:20 +08:00
    meeken
        1
    meeken  
    OP
       2019-09-14 17:23:59 +08:00
    纠正:vuex 可能 17 年就有了,但是那个项目当时没安排上(逃
    woncode
        2
    woncode  
       2019-09-14 18:01:23 +08:00 via Android
    这种事情就是必须要靠踩坑才能意识到的,即使学了很多设计模式和代码规范,如果没有痛的领悟,还是不知道什么时候该注意、使用,但是能加快你的意识
    scalaer
        3
    scalaer  
       2019-09-14 18:16:39 +08:00 via iPhone
    有些人的代码品位低,自尊心几乎没有。当你对他的代码提出怀疑时候,这种人总想笑着打发过去,当你试图继续时候,他会说你干嘛那么严肃,到最后像你的问题一样。遇到要接手别人代码的时候,能躲就躲
    xuanbg
        4
    xuanbg  
       2019-09-15 08:32:07 +08:00
    已经差不多把自己以前制造的屎山吃干净了,好有成就感,想想就兴奋,忍不住马上就要再去啃上几口。
    justin2018
        5
    justin2018  
       2019-09-15 10:2:44 +08:00
    自己体验一次 就知道了 哈哈哈~
    alcarl
        6
    alcarl  
       2019-09-15 10:25:52 +08:00 via Android
    设计,计划,那是什么( )
    meeken
        7
    meeken  
    OP
       2019-09-15 11:38:01 +08:00
    @xuanbg hhhh 别把
    meeken
        8
    meeken  
    OP
       2019-09-15 11:39:20 +08:00
    @alcarl 没有的事 TUT
    meeken
        9
    meeken  
    OP
       2019-09-15 11:40:05 +08:00
    @mggis0or1 TUT 和懂注释会耐心解答的人交流还是很舒服的
    beastk
        10
    beastk  
       2019-09-16 09:30:20 +08:00 via iPhone
    靠山吃山,哈哈哈
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     4253 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 31ms UTC 01:02 PVG 09:02 LAX 17:02 JFK 20:02
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86