V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
asanelder
V2EX  ›  程序员

8 层嵌套, 400 多行代码的函数。。。

  •  
  •   asanelder · 2020-06-09 21:13:10 +08:00 · 8947 次点击
    这是一个创建于 473 天前的主题,其中的信息可能已经有所发展或是发生改变。

    遇到一个老的项目,有一个函数是 8 层嵌套,if 套 while 再套 if 再套 while 再套 if ....,而且每个条件判断中,各种&& 套 || 再套 &&,这个 8 层嵌套俺数了一下,一共 400 多行代码。。。

    让俺感觉到奇怪的是,之事从事这个项目的老员工对这个函数竟然没有丝毫的意见,他们似乎很平静。

    那么问题来了,俺之前受的教育是,函数应该尽量短小,嵌套应该尽量浅。所以遇到这个函数俺自然感觉浑身不适,但那些老员工似乎都很平静。是俺太笨了,理解不了这种 8 层嵌套,还是俺太矫情,太理想主义了,太教条了,还是老员工已经习惯了?

    求解惑

    第 1 条附言  ·  2020-06-10 14:38:00 +08:00
    看到老铁们的回复,俺释然了,原来俺这种情况不是个例,心态平静了很多
    96 条回复    2020-06-15 15:50:59 +08:00
    lmmortal
        1
    lmmortal   2020-06-09 21:14:50 +08:00 via iPhone
    老员工见怪不怪了,这种东西谁都懒得动。动好了没好处,动坏了就捅破天了所以都不愿意动
    singerll
        2
    singerll   2020-06-09 21:15:56 +08:00 via Android   ❤️ 8
    你改了呗,以后系统有问题甭管是啥原因,第一个怀疑的就是你改的代码的问题,让你好好查个遍再查其他
    luckyrayyy
        3
    luckyrayyy   2020-06-09 21:18:44 +08:00
    首先你得看好不好改啊,是不是确实极其复杂,不好下手?
    或者说里面其实有大量裁剪,不一定复杂多真的这么高,这么写只是为了好理解?
    另外从事这个项目的老员工都接手过这一块的逻辑吗?说不定人家负责别的模块见都没见过这里的代码?
    最后都没问题的话,你改呗...即优化了代码,又满足了自己强迫症,多好啊。
    asanelder
        4
    asanelder   2020-06-09 21:21:39 +08:00   ❤️ 2
    @lmmortal
    @singerll

    关键是有个功能要在这基础上改,俺修改的时候瑟瑟发抖,生怕改坏了(注意,这个函数没有相关测试)

    这感觉就像是拿着一个很脆弱的易碎品,生怕摔了。
    又像是你去蹲坑,发现停水很久了,坑里已经被 S 塞满了,而你不得不忍着恶心蹲下
    asanelder
        5
    asanelder   2020-06-09 21:23:11 +08:00
    @luckyrayyy #3 看了一下 git 记录,有 6 个人修改过,其中 4 个已经离职,还有 2 个健在。。。
    prenwang
        6
    prenwang   2020-06-09 21:24:19 +08:00   ❤️ 2
    没事的, 反正蹲下拉出来的也是 s
    asanelder
        7
    asanelder   2020-06-09 21:25:04 +08:00
    @prenwang #6 这话俺看听
    dswyzx
        8
    dswyzx   2020-06-09 21:28:54 +08:00
    敢承担后果就敢上手搞 bug
    无非就是修 bug 嘛
    786375312123
        9
    786375312123   2020-06-09 22:11:29 +08:00
    如果是 legacy code 就不要动,如果需要维护的话其实问一问改过的同事,也没什么大不了的。你们又不是微软,能遇到 80 年代写的代码。
    silvernoo
        10
    silvernoo   2020-06-09 22:20:46 +08:00   ❤️ 1
    flutter 表示 8 层嵌套根本不叫事
    miao666
        11
    miao666   2020-06-09 23:31:35 +08:00 via Android
    黑猫白猫,能跑就是好猫
    asanelder
        12
    asanelder   2020-06-09 23:32:02 +08:00
    @silvernoo #10 还没开始学 flutter,表示十分期待
    x86
        13
    x86   2020-06-10 00:26:59 +08:00 via iPhone
    没问题就不要改,要改就准备好出问题背锅的准备…
    Vegetable
        14
    Vegetable   2020-06-10 00:47:16 +08:00   ❤️ 15
    他们可能也年轻过,迷茫过,尝试过,服了。
    charlie21
        15
    charlie21   2020-06-10 00:58:33 +08:00
    应该该成状态机
    xstmjh
        16
    xstmjh   2020-06-10 01:01:53 +08:00
    一看就是没测试
    XanderChen
        17
    XanderChen   2020-06-10 04:05:52 +08:00 via Android
    我倒是觉得 if while 与或非各种嵌套的代码挺好改的,

    你用文本的形式或者思维导图把所有情况列出来就行了,按图索骥呗。
    ericgui
        18
    ericgui   2020-06-10 04:24:34 +08:00
    从理论上说,你应该改。从现实上,你先问问老板,然后再考虑下一步。
    IllBeBack
        19
    IllBeBack   2020-06-10 05:46:37 +08:00   ❤️ 4
    这么多逻辑写在一起在 Debug 的时候可能还清晰一点,IDE 都有 if else 及 while 的折叠功能,功能区块还可以用 region 包起来,说不定还很直观。

    如果拆成 N 个函数,Debug 的时候东跳西跳可能完全理不清头绪。理论上函数应该尽量短小,但实际上要看好不好 Debug,好不好理解。

    也就 400 行,你可以试着理一下,如果不是把一垞屎变成 N 垞屎,那就可以跟领导邀功了。
    Tony042
        20
    Tony042   2020-06-10 07:26:13 +08:00
    试下 matlab 的 state flow?貌似挺有效解决这类问题的
    evilic
        21
    evilic   2020-06-10 08:03:34 +08:00
    干好事有好报没?
    lasuar
        22
    lasuar   2020-06-10 08:12:06 +08:00
    这个一般是传承下来的,你要改它,准备好加班和挨骂的风险。
    isnullstring
        23
    isnullstring   2020-06-10 08:18:59 +08:00   ❤️ 1
    改出问题还得挨骂,改好了好像也不会加薪
    SO
    Vitta
        24
    Vitta   2020-06-10 08:19:46 +08:00 via iPhone
    我见过 7000 行的
    whywhywhy
        25
    whywhywhy   2020-06-10 08:20:29 +08:00   ❤️ 3
    偷偷的重新编写它,然后反复测测测,确保行为一致。然后找一个黄昏的早晨,轻轻的替换掉它。
    JieS
        26
    JieS   2020-06-10 08:24:10 +08:00 via iPhone   ❤️ 3
    @whywhywhy "你好骚啊"
    chaodada
        27
    chaodada   2020-06-10 08:30:52 +08:00 via iPhone
    这算啥,年前写了一个功能,整体用十几个函数实现,最大的函数 1300 行🤨,上个月功能大还,我又将它拆分成了三个递归函数,这种函数一般功能不变,不会动的,动一动,公司就倒闭了🤣🤣🤣
    sriidtied
        28
    sriidtied   2020-06-10 08:31:21 +08:00
    @whywhywhy 又是一个不眠夜
    littleshy
        29
    littleshy   2020-06-10 08:36:42 +08:00   ❤️ 1
    严以律己,宽以待人。
    fxxwor99LVHTing
        30
    fxxwor99LVHTing   2020-06-10 08:42:06 +08:00
    除非有问题,否决千万不要动。
    rhwood
        31
    rhwood   2020-06-10 08:51:59 +08:00
    默默地看了一下我写的一个 200 行的函数,能用就好,自己都懒的改
    php01
        32
    php01   2020-06-10 08:57:17 +08:00
    这或许是他们的生存智慧呢?也说不定的
    wanzi123
        33
    wanzi123   2020-06-10 09:04:38 +08:00
    前几天经历了一个方法里 5 层 for 循环哈哈
    hejw19970413
        34
    hejw19970413   2020-06-10 09:07:31 +08:00
    远古代码 尽量不要动
    CodingNaux
        35
    CodingNaux   2020-06-10 09:08:03 +08:00 via iPhone
    千万别动,哪怕格式化一下,留下 commit,以后 blame 出来都找你
    smallyu
        36
    smallyu   2020-06-10 09:09:05 +08:00
    我刚毕业的时候也这么想,各种代码规范,应该怎样应该怎样。后来遇到了一个多月一个 crud 项目的需求,而且中间需求变了三四回,道貌岸然敏捷开发,基本上重写三四回。
    dabang007
        37
    dabang007   2020-06-10 09:11:26 +08:00
    我做毕业设计时候,看到师兄的 VC 代码,总共 1W 多行,但其中一个函数就 8000 多行....
    zzzmh
        38
    zzzmh   2020-06-10 09:13:48 +08:00
    这才哪到哪,我在外包打杂的时候,随便一个 js 都是几千行,连 function 都不一定有,就见面先怼个 2000 行逻辑。。。还见过 for 循环一万次,然后得到的值被注释了,没起到任何作用。
    jorneyr
        39
    jorneyr   2020-06-10 09:16:54 +08:00
    IBM Domino 有个核心函数的代码有 1 万多行呢,脱离了业务逻辑谈代码,不敢随意下定论。
    xiaoyang7545
        40
    xiaoyang7545   2020-06-10 09:18:37 +08:00
    如果是函数内的东西随便他里面怎么搞。能得到正确结果就是了。如果是流程的话就比较恶心。后面要是有需求变化就难改。
    dog82
        41
    dog82   2020-06-10 09:21:31 +08:00
    你能把它改成 3 层吗?不行就不要动
    cxknmsl
        42
    cxknmsl   2020-06-10 09:23:49 +08:00
    @zzzmh,牛批,这场面真没见过
    Hallelu
        43
    Hallelu   2020-06-10 09:25:19 +08:00
    我们公司很多函数都在一两千行,各种业务逻辑判断。
    neroransom
        44
    neroransom   2020-06-10 09:28:55 +08:00 via Android
    这种 if else 又不是一个人写出来的,有时和完全重构相比,直接加一个 else 才是最优选项。
    lyz1990
        45
    lyz1990   2020-06-10 09:33:31 +08:00
    手上维护的项目,1000 行以上的函数五六个吧,所有的历史作者都离职了。
    zhuweiyou
        46
    zhuweiyou   2020-06-10 09:35:00 +08:00
    几千上万行一个文件,都是很正常的事情,大惊小怪?
    yuchenyang1994
        47
    yuchenyang1994   2020-06-10 09:36:43 +08:00
    我见过 3000 行的
    fhsan
        48
    fhsan   2020-06-10 09:37:45 +08:00
    代码 commit+1,离职+1,成为老坑
    ma836323493
        49
    ma836323493   2020-06-10 09:52:19 +08:00   ❤️ 1
    关键是有个功能要在这基础上改,俺修改的时候瑟瑟发抖,生怕改坏了(注意,这个函数没有相关测试)

    这感觉就像是拿着一个很脆弱的易碎品,生怕摔了。
    又像是你去蹲坑,发现停水很久了,坑里已经被 S 塞满了,而你不得不忍着恶心蹲下



    以前同事也是这么想的,可能原先只有七层嵌套, 他怕改出问题,一个稳妥的办法,八层嵌套
    galikeoy
        50
    galikeoy   2020-06-10 09:56:46 +08:00
    那就再加一层 if #滑稽
    mbtfdwlx
        51
    mbtfdwlx   2020-06-10 10:03:38 +08:00
    我在维护老项目时候遇到过这种情况,稳妥一些的办法,首先要在原来的基础上做好新需求。上线后再把原来的代码一点点重写掉,扔到测试服,多测试,最后体验服跑上一段时间后没问题,就可以上线了...
    statement
        52
    statement   2020-06-10 10:03:56 +08:00
    如果你在这家公司待了三年以上,可以考虑重现一个实现替换,但也别改。
    如果你刚来这家公司,且不是大牛。有这种想法可以但最好别和别人说。
    vevlins
        53
    vevlins   2020-06-10 10:04:39 +08:00
    四百多行我见过有二十个 ifelse 的,有时候代码烂是工期、需求、技术人员多方面一起造成的,有它的历史背景在。 如果要改就找个工期宽裕的,测试愿意配合,加上单测。
    whypool
        54
    whypool   2020-06-10 10:10:30 +08:00
    事实证明代码洁癖要不得
    如果再加一个需求,你还是会用 if,再去嵌套
    Doracis
        55
    Doracis   2020-06-10 10:11:34 +08:00
    我可能就是写了八层 if else 的程序员,没办法,开发周期短,需求变更频繁,本来我都计划的好好地,用一个 if else 解决,谁知甲方中途加需求改设计方案,后台加字段加状态加各种 flag,我也抓狂啊

    不过好在每次写 if else 我都会留下注释,为什么加每一层判断以及要干嘛这种的,算是方便后期维护吧,毕竟代码放了三个月再看,亲妈都不认识了

    这种代码俗称屎山,屎山不是一日堆成的,你要想撬动屎山就做好被屎淹没的勇气,撬不动就再堆点屎,浮冰之下用户也看不到屎山,再说了就大部分程序员的这个代码水平,芳古流传不可能了,十七八年基本就会整体换一代框架, 没必要,真的没必要
    micean
        56
    micean   2020-06-10 10:20:16 +08:00
    老纠结嵌套和行数,不如写上注释,啥都不是事
    jasonding
        57
    jasonding   2020-06-10 10:25:44 +08:00   ❤️ 1
    想起我写的一个类,1400 行,其中一个函数是 excel 导入,差不多占了近千行。两个 sheet,涉及 7 层数据结构,sheet1 是前四层,sheet2 是后四层,其中一个是映射层,这是基础数据结构。然后还有 excel 模板校验、实际数据格式校验、脚本逻辑校验、穷举遍历、组合计算、数据入库等实际业务逻辑。总共改版三次,其中第三版是兼容版,要求兼容老的 excel 模板,同时支持新的 excel 模板导入,我 TM 都快疯了。
    codergrowing
        58
    codergrowing   2020-06-10 10:28:39 +08:00
    8 层算什么,前一段接了一个项目,一个函数嵌套层级有 12 层……真的是理逻辑理到怀疑人生
    zhangyangkam1
        59
    zhangyangkam1   2020-06-10 10:44:33 +08:00
    从某种意义上来说写个十几层嵌套也不出错一直用下来也算挺厉害的
    tremblingblue
        60
    tremblingblue   2020-06-10 10:48:11 +08:00
    所以一个 if 上去保平安 然后下个月再加一个.
    nightwitch
        61
    nightwitch   2020-06-10 10:56:32 +08:00
    能打断点的话,if-else 的 400 行的函数还算凑合吧,搞清楚哪个分支会在什么情况进入就行了,if-else 多了就是作用域比较讨厌,debugger 可以帮你看到当前作用域可以看到哪些变量。

    如果你的业务代码需要用 400 行代码来描述,你拆成小函数也是差不多的,一样要走不同的分支,在不同的小函数里跳来跳去。
    Cmdhelp
        62
    Cmdhelp   2020-06-10 10:56:59 +08:00
    改一个公司倒闭
    wayslog
        64
    wayslog   2020-06-10 11:51:23 +08:00
    我就不说我曾经维护过一个 1k+行的 python 函数。。。参数十几个,还有 *args **kwargs 。。。我花了一个月才读通它的逻辑。。。
    vcode
        65
    vcode   2020-06-10 12:04:21 +08:00
    你是新手啊
    zyy314680012
        66
    zyy314680012   2020-06-10 12:09:36 +08:00 via Android
    如果是我,肯定不改
    herexf
        67
    herexf   2020-06-10 12:16:43 +08:00 via Android
    所以一直很好奇怎么才能优化这种,非专科,只是偶尔也会看到类似的代码,SAP 中
    herexf
        68
    herexf   2020-06-10 12:20:13 +08:00 via Android
    所以一直很好奇怎么才能优化这种,非专科,只是偶尔也会看到类似的代码,SAP 中
    bxb100
        69
    bxb100   2020-06-10 12:32:59 +08:00
    没有单测和边缘测试不要改
    wangyzj
        70
    wangyzj   2020-06-10 12:33:35 +08:00   ❤️ 1
    代码行数,复杂度和是否可优化没半毛钱关系
    业务拆分和是否能复用才是
    winglight2016
        71
    winglight2016   2020-06-10 12:52:21 +08:00
    哈哈哈,400 行还真不算多,我写过 4000 多行的代码,就是为了根据规则计算支付金额,业务逻辑太复杂,没有更好的办法。
    celeron533
        72
    celeron533   2020-06-10 13:18:35 +08:00
    会不会以前是 16 层嵌套,800 行代码。。。
    hu8245
        73
    hu8245   2020-06-10 13:54:42 +08:00
    如果逻辑清晰也没什么不合适的吧,当然从维护性来说,是下降了。
    justin2018
        74
    justin2018   2020-06-10 14:16:05 +08:00   ❤️ 1
    ![xNfesUX]( ) 想到了这个图
    sigl0p
        75
    sigl0p   2020-06-10 15:23:55 +08:00
    400 行不算长的,我接手过 C C++ 函数动则几千行
    la2la
        76
    la2la   2020-06-10 15:34:49 +08:00
    见过 java spring 一个类 7000+行的么?改一个标点符号就要备份
    Chowe
        77
    Chowe   2020-06-10 16:09:53 +08:00 via iPhone
    更可怕的是
    #if
    #else
    jsjgjbzhang
        78
    jsjgjbzhang   2020-06-10 16:40:02 +08:00
    想提升自己就去改 想给自己找麻烦就提交
    Keyes
        79
    Keyes   2020-06-10 17:24:13 +08:00
    @justin2018 哈哈哈读了一下竟觉得没毛病
    noobsheldon
        80
    noobsheldon   2020-06-10 17:24:46 +08:00
    楼主的帖子好喜欢用“俺”,总是让人想起《熊出没》里的熊二
    GopherTT
        81
    GopherTT   2020-06-10 18:12:33 +08:00
    @noobsheldon hhah 特地数了下 八个:)
    KasonPasser
        82
    KasonPasser   2020-06-10 18:22:28 +08:00
    好想见识一下,我一般都是复制一个新的函数出来改,原来的能不动尽量不动。
    改完了测试没问题再迁移,不过一般出问题了都是没有好结果。
    确实想改送你六个字:慎之慎之慎之。
    deplives
        83
    deplives   2020-06-10 18:29:07 +08:00
    我见过一个实习生写的 Python request handle 多达 1500 多行,仔细一看,他一个 handle 处理了 get post put delete 不同请求
    w516322644
        84
    w516322644   2020-06-10 18:43:21 +08:00
    @justin2018 你是不是在黑 php,我遇见过 java 这么类似写的。
    asanelder
        85
    asanelder   2020-06-10 18:46:50 +08:00
    @codergrowing #58 哈哈,笑尿了
    zuokanyunqishi
        86
    zuokanyunqishi   2020-06-10 18:58:30 +08:00 via Android
    你是没见过 800/1500 行的函数🐶
    cwek
        87
    cwek   2020-06-10 20:52:45 +08:00
    没坏,别动
    akira
        88
    akira   2020-06-10 20:56:27 +08:00
    老员工都知道 这种代码不能动,一动就必然会死人.
    sampeng
        89
    sampeng   2020-06-11 07:28:14 +08:00 via iPhone
    去年这类帖子出来还是尽量自己慢慢重构了。除非是算法类,普通逻辑类的大函数就没有改不掉的。是会有风险,现在程序员都居安思危到这个地步了?太可怕了…
    codingbody
        90
    codingbody   2020-06-11 08:05:54 +08:00 via iPhone
    spring jdbctemplate 中 setvalue 方法 200 多行全是 if else else if
    soulmt
        91
    soulmt   2020-06-11 08:56:55 +08:00
    不要慌,常见操作, 老代码别动就对了
    Daniel17
        92
    Daniel17   2020-06-11 13:42:34 +08:00
    一个 switch800 行的见过没。。还全部写在 controller 层
    royan
        93
    royan   2020-06-11 14:08:42 +08:00
    补测试,动手改。大不了跑路,怕什么[狗头 /摊手]
    wisetc
        94
    wisetc   2020-06-13 11:09:17 +08:00 via iPhone
    你如果能改并且保证不出问题也要看看做了这件事对谁有利,是否在为前人背锅,成为搏傻游戏里的傻人呢?如果要扩展,并且之前开闭原则都不遵守,这家公司的管理是不是有问题呢?这个问题是你的吗?
    EscYezi
        95
    EscYezi   2020-06-13 14:34:17 +08:00 via iPhone
    还真拆过一个 400 行的,按业务逻辑拆成了三个。后来有需求要在这块加东西,还好之前拆了,不然真的要吐
    ruzztok
        96
    ruzztok   2020-06-15 15:50:59 +08:00
    逻辑没有问题、不影响性能、没有复用价值的 1000 层又怎样??现实一点,不要看太多阿里巴巴的编程手册和一些编码规范之类的书
    关于   ·   帮助文档   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   952 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 20:43 · PVG 04:43 · LAX 13:43 · JFK 16:43
    ♥ Do have faith in what you're doing.