一个文件(或函数)代码很长是严重的问题吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
virushuo

一个文件(或函数)代码很长是严重的问题吗?

  •  
  •   virushuo Apr 2, 2011 7314 views
    This topic created in 5504 days ago, the information mentioned may be changed or developed.
    从 @newblue 给 @livid 的意见 http://www.v2ex.com/t/10859 而起,觉得这问题可以讨论。

    我认为“代码过长是不好的变成习惯”的说法已经过时了。在过去编辑器不够发达,语言能力不够强的时候,一个函数中过长的代码确实难以维护和调试。但现在已经有很多足够好的编辑器和IDE,并不会感觉到麻烦。

    比如Xcode支持的 #pragma mark ,就算一个.m文件再长,只要有打这种mark的良好习惯,都会容易组织代码,维护并不困难。

    调试也一样,如果直接用gdb调试,过长的函数也很麻烦。但现在有了更多的静态和动态分析方法,很多时候不需要再用gdb一行一行的调代码了。(动态语言就更没这麻烦了)

    而文件太多,要在文件之间来回跳来跳去,反而不如 #pragma mark 这种标记容易使用。

    所以我认为以代码长已经可以看作一种编程风格,而不是一种坏习惯。当然代码逻辑混乱,另当别论。

    大家的看法呢?
    27 replies    1970-01-01 08:00:00 +08:00
    newblue
        1
    newblue  
       Apr 2, 2011
    如果一段代码其中某些部分可以独立开来的话,把可以重用的部分抽出来,是一个比较好的处理方法。

    像Python这种靠缩进确定代码块的语言,不合适台长的代码块。这是修改v2ex的体会。
    crazycookie
        2
    crazycookie  
       Apr 2, 2011
    只要这个文件或者函数是相对独立的,他里面的很多操作原子 只有它本身使用的,我觉得再长都无所谓,只要配上详细的注释 很多功能函数本来就是复杂的东西
    曾经见过 一个函数一页多,头部注释两页的函数一枚,是复杂的算法函数
    virushuo
        3
    virushuo  
    OP
       Apr 2, 2011
    @newblue 是说错进层次太多吗?那个倒确实很头疼。
    dreamer
        4
    dreamer  
       Apr 2, 2011
    我觉得一个函数的代码太长会不太舒服,如果里面再包含很多的 if else, switch case 就有点儿恐怖了。虽然很多 IDE 对于函数都有很好的代码管理功能,但是我想还有一些人非常喜欢用 TextMate, VIM, Emacs 等编辑器做开发,所以如果一个 if block 里面的代码如果太长,还是建议抽取出来,会使结构更清晰一点。
    crazycookie
        5
    crazycookie  
       Apr 2, 2011
    @newblue 个人觉得 代码好坏的判断依据:不是你修改的难易程度作为依据的。而是你是否能快速的读懂,作者的设计思路是否明确 为依据。 毕竟,代码写完之后 是用来执行 和 应用的 很少有代码是经常性的拿来修改的
    dreamer
        6
    dreamer  
       Apr 2, 2011
    @newblue python 的缩进如果超过4层,可以想象有多难看。XD
    Sai
        7
    Sai  
       Apr 2, 2011
    只要分类清晰,易于开发协作,将同一类函数放一个文件不是什么大问题。

    不过我是很有整理癖的人,iOS 的 Project 不仅在 xcodeproj 内要分门别类,就算是 App 实体文件夹我也会按 Views / View Controllers 等等整理。

    另外 PHP 的话如果代码都写在一个文件里那么执行的时候那整个文件都需要载入到内存中(比如老 PB 的那种组织形式),执行效率上也许会打折扣。当然在 APC, eAccelerator 的帮助下性能损耗可以忽略不计。

    @newblue 指的过长是代码中存在大量的重复代码(比如举例的那个 select 表单),这样的代码是需要抽象成通用函数进行重构的。
    newblue
        8
    newblue  
       Apr 2, 2011
    @virushuo
    Python这种代码不管缩进的多少,只要太长都会产生严重的问题,中间要是有一行没对齐,都要出问题。

    @Sai
    不管一段长代码是否春在大量重复的代码,适当的把不属于该段代码的功能的代码独立出来,都是应该的。
    以后可以重用到也是一个好处。
    leben
        9
    leben  
       Apr 2, 2011
    今天早上还在想这个问题,有时候看别人的代码,跳来跳去的函数,找函数在哪就是一件很痛苦的事。
    keakon
        10
    keakon  
       Apr 2, 2011
    对机器来说,代码长度从来不是问题,但问题是你得给人来读。

    假设你按照一份说明书去为你的电脑加硬盘,这份说明书花了10页来告诉你怎么拆第一颗螺丝,又花了10页告诉你怎么拆第二颗…你会不会觉得很无语?
    chone
        11
    chone  
       Apr 2, 2011
    如果是面向过程的话可能还行(不过分清模块的话应该也不是很长),面向对象的话,如果算法不复杂的话,代码过长往往就意味着给某些类塞了太多的东西。至于python缩进的问题,我觉得函数代码长度尽量控制在一屏之内是一种美德。
    9hills
        12
    9hills  
       Apr 2, 2011
    http://www.kernel.org/doc/Documentation/CodingStyle
    80x24的标准终端上,一到两屏,也就是24~48行。。,例外就是大规模且互不干扰的的switch,

    这个标准虽然有人会说是 古老,针对C,不合时宜。。。。
    但是一个函数48行,尤其是python这种连{}都没有的语言,大部分情况下就够了
    franksin
        13
    franksin  
       Apr 2, 2011
    一个函数如果做了太多的事情,会被后来维护代码的人偷偷BS的吧。。。
    virushuo
        14
    virushuo  
    OP
       Apr 2, 2011
    @9hills 那个我当然知道,但现在的设备早就不是这样了。同时用几个超过21寸显示器都是正常的。
    chone
        15
    chone  
       Apr 2, 2011
    @virushuo 屏幕可以外接,人脑可不能,一个代码块短小主要是能在逻辑上显得更清晰。
    iwinux
        16
    iwinux  
       Apr 2, 2011
    @virushuo 从测试的角度来看,与一个很长的函数相比,一堆短小的函数比较容易做单元测试。
    clowwindy
        17
    clowwindy  
       Apr 2, 2011 via Android
    代码长度有时更多的暗示着设计问题。就我自己来说,一般一个类到了一千行的时候,会感到一种bad smell,这时就开始考虑按照方面来拆分这个类了。
    可读性方面,我觉得这个受编辑器的影响很大,比方说eclipse里习惯了ctrl+O以后,很少就会用拖滚动条来定位函数了,而对于没有定位功能的编辑器来说,函数过多就成了一个灾难。
    dreampuf
        18
    dreampuf  
       Apr 2, 2011
    除非有绝对的拓展必要..
    否则用空行来区分逻辑..不拆分文件.

    vimer.


    以前用维修死丢丢写C#时.
    一个类往往就一行代码起作用.
    Platinum
        19
    Platinum  
       Apr 2, 2011
    这个问题真的是 virushuo 问的么……

    如果程序的运行结果跟我想的完全不一样,我不会认为是编译器错了,一定是我错了

    如果一个函数有 200 行,我会认为一定是我写错了,而不是对行数的要求过时了

    如果缩进有 5 层,我会去寻找一定有哪里可以缩减层数,而不是在编辑器里设置一个缩进=2空格

    上述情况也许真的有例外,但我会忽略掉,假设例外的不存在,就像假设 md5 不会碰撞一样
    Kymair
        20
    Kymair  
       Apr 2, 2011
    我还是觉得函数过长是肯定有问题的,除了少数为了优化性能的极端情况。

    函数提供的不仅是语义上的区分,还有更重要的实际信息隐藏用途。举个例子,将本应抽取成几个函数的语句放到一个里面,如果用i当counter做了循环,那么下文再次用到循环时就只有两个选择:换一个变量j,或者重用i之前确保它被还原成了初始值。这无疑是把机器应该做的事情推给了程序员。也许你说,现在大多用foreach或iterator或block之类,但这里只是一个例子,一个大函数,需要程序员小心翼翼的控制所有visible的变量的访问,而这本来是可以用函数来隐藏的。

    即使单从程序员理解角度上来讲,一个函数跟一个mark对比,都有一个名字,但多提供了输入参数和返回值的信息,返回值到输入参数的映射,这是函数的本质含义。
    virushuo
        21
    virushuo  
    OP
       Apr 2, 2011
    @Platinum 是我问的。我觉得一些说法确实过时了。比如我现在就宁可在一个.m里面写很多,也不愿意拆开,因为xcode足够方便,处理一个比处理一堆文件方便多了。我的本意是,所谓的编程习惯是不是应该根据实际情况有一些变化,而不能当作判断的永恒标准。
    apoclast
        22
    apoclast  
       Apr 2, 2011
    个人不太喜欢这样, 不过偶尔看一些著名开源项目代码的时候, 发现这样情况也蛮普遍的, 所以不想多说什么了
    virushuo
        23
    virushuo  
    OP
       Apr 2, 2011
    另外说一个函数太长不好的人估计是没怎么看过大的开源项目,比如你去看看lucene/mapreduce,长的吓死人。
    virushuo
        24
    virushuo  
    OP
       Apr 2, 2011
    @Platinum 而事实上,编译器也是经常出错的,写内核的发现结果不对先去debug gcc是很常见的啊。
    Kymair
        25
    Kymair  
       Apr 2, 2011
    @virushuo 我认同编程习惯确实应该与时俱进。不过似乎在这个问题上,感觉似乎是相反的方向:D 比如以前都说C函数调用开销大,得多inline。现在机器性能越来越强大,IDE和Editor的功能越来越丰富,似乎是向切分成更多文件/函数的方向发展。
    phpuser
        26
    phpuser  
       Apr 2, 2011
    系统里面C代码单文件超30K行,单函数超3K行,全量编译超过4小时的家伙,无语飘过。。。。lolz...
    phpuser
        27
    phpuser  
       Apr 2, 2011
    好在VIM强大,要是我也用UE之类的,估计早崩溃了。看代码、找错误真是非常痛苦的事情。mark多了自己都找不到哪个mark是哪个了。不过在一个体系内,个人的力量是非常渺小的。。何况有些还是世纪性的遗留问题。。
    About     Help     Advertise     Blog     API     FAQ     Solana     992 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 60ms UTC 20:13 PVG 04:13 LAX 13:13 JFK 16:13
    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