5200,关于腐烂的代码,德国牧羊犬

精品专栏

 
  • 死磕 Java 并发

  • 死磕 Sharding-jdbc

  • 死磕 Spring 之 IOC

出处:http://blog.2baxb.me/archives/1343


1.摘要

最近写了不少代码,review了不少代码,也做了不少重构,总归是对着烂代码作业何慈茵了几周。为了抒情一下这几周里好几回抵达溃散边际的心情,我决议写一篇文章谈一谈烂代码的那些事。 这儿是上篇,谈一谈烂代码发作的原因和现象。

2.写烂代码很简略

刚入程序员这行的时分常常听到一个观念:你要把精力放在ABCD(需求文档/功用规划/架构规划/了解原理)上,写代码仅仅把主意翻译成编程言语罢了,是一个没什么技能含量的作业。

其时的我在听到这种观念时会有一种近似于高冷的不屑:你们便是一群傻X,底子不了解代码质量的重要性,这么下去早晚有一天会踩坑,呸。

可是几个月之后,他们好像也没怎样踩坑。而跟着编程技能一直在不断发展,带来了更多的我从前认为是傻X的人加入到程序员这个职业中来。

言语越来越高档、封装越来越完善,各种技能都在协助程序员进步出产代码的功率,依托5200,关于腐朽的代码,德国牧羊犬层层封装,程序员真的不需求了解一丁点技能细节,只要把需求里的内容逐行翻译出来就能够了。

许多程序员不知道要怎样安排代码、怎样进步运转功率、底层是根据什么原理,他们写出来的是在我心目中烂成一坨翔相同的代码。

可是那一坨翔相同代码居然他妈的能正常作业。

即便我认为他们写的代码是坨翔,可是从不触摸代码的人的视角来看(比方说你的boss),代码编译过了,测验过了,上线运转了一个月都没出问题,你还想要苛求什么?

所以,即便不甘愿,也有必要供认,时至今日,写代码这件事自身没有那么难了。

3.烂代码终究是烂代码

可是偶然有那么几回,写烂代码的人离任了之后,作业好像又变得不相同了。

想要修正功用时却发现程序里充满着各种无法了解的逻辑、改完之后不可思议的bug一个接一个,接手这个项目的人开端漫无目的的加班,而且本来一个挺达观开畅的人逐渐的开端喜爱问好他人祖先了。

我总结了几类常常被艹祖先的烂代码:

3.1.含义不明

才能差的程序员简略写出含义不明的代码,他们不知道自己终究在做什么.

就像这样:

  1. public void save() {


  2. &n性论题bsp;   for(int i=0;i<100;i++) {


  3.         //避免保存失利,重试100次


  4.         document.save();


  5.     }


  6. }

关于这类程序员,我一般主张他们转行。

3.2.不说人话

不说人话是新手最常常呈现的问题,直接的体现便是写了一段很简略的代码,其他人却看不了解。

比方下面这段:

  1. public boolean getUrl(Long id) {


  2.     UserProfile up = us.getUser(messms.get(id).getMessage().aid);


  3.     if (up == null) {


  4.         return false;


  5.     }


  6.     if (up.type == 4```| ((up.id >> 2) & 1) == 1) {


  7.         return false;


  8.     }


  9.     if(Util.getUrl(up.description)) {


  10.     &nb昌吉气候sp;   return true;


  11.     } else {


  12.         return false;


  13.     }


  14. }

许多程序员喜爱简略的东西:简略的函数名、简略的变量名、代码里辗转反侧只用那么几个单词命名;能缩写就缩写、能省掉就省掉、能兼并就兼并。这类人写出来的代码里充满着各种g/s/gos/of/mss之类的全世界没人懂的缩写,或许一长串不知道在做什么的接连调用。

还有许多程序员喜爱杂乱,各种宏界说、位运算之类写的不着边际,生怕代码让他人一会儿看懂了会显得自己水平不行。

简略的说,他们的代码是写给机器的,不是给人看的。

3.3.不恰当的安排

不恰当的安排是高档一些的烂代码,程序员在写过一些代码之后,有了根本的代码风格,可是关于规划大一些的工程的掌控才能不行,不知道代码应该怎样解耦、分层和安排。

这5200,关于腐朽的代码,德国牧羊犬种反形式的现象是常常会看到一段代码在工程里拷来拷去;某个文件里放了一大坨堆砌起来的代码;一个函数堆了几百上千行;或许一个简略的功用七拐八绕的调了几十个函数,在某个难以发现的鄙陋的小角落里静静的调用了某些要害逻辑。

这类代码大多杂乱度高,难以修正,常常一改就崩;而另一方面,发明了这些代码的人倾向于修正代码,害怕发明代码,他们甘愿让本来杂乱的代码一步步变得更杂乱,也不愿意重新安排代码。当你面临一个几千行的类,问为什么不把某某逻辑提取出来的时分,他们会说:

“可是,那样就多了一个类了呀。”

3.4.假定和短少笼统

相关于前面的比方,假定这种反形式呈现的场景更频频,把戏更多,始作俑者也更难以自己认识到问题。比方:

  1. public String loadString() {


  2.     File file = new File("c:/config.txt");


  3.     // read something


  4. }

文件途径改变的时分,会把代码改成这样:

  1. public String loadString(String name) {


  2. 聂耳    File file = new File(name);


  3.     // read something


  4. }

需求加载的内容更丰厚的时分,会再变成这样:

  1. public String loadStr5200,关于腐朽的代码,德国牧羊犬ing(String name) {


  2. &nbhersp;   File file = new File(name);


  3.     // read something


  4. }


  5. public Integer loadInt(String name) {


  6.     File file = new File(name);


  7.     // read something


  8. }

之后或许会再变成这样:

  1. public String loadString(String name) {


  2.     File file = new File(name);


  3.     // read something


  4. }


  5. public String loadStringUtf8(String name) {


  6.     File file = new File(name);


  7.     // read something


  8. }


  9. public Integer loadInt(String name) {


  10.  &5200,关于腐朽的代码,德国牧羊犬nbsp;  File file = new File(精约风格装饰name);


  11.     // read something


  12. }


  13. public String loadStringFromNet(String url) {


  14.     HttpClient ...


  15. }


  16. public Integer loadIntFromNet(String url) {


  17.     HttpClient ...


  18. }

这类程序员往往是项目组里开发功率比较高的人,可是许多的事务开发作业导致他们不会做剩余的考虑,他们的口头禅是:“我每天要做XX个需求”或许“先做完需求再考虑其他的吧”。

这种反形式体现出来的结果往往是代码很难复用,面临deadline的时分,程序东南亚员火急的想要把需求履行成代码,而这往往也会是个循环:写代码伊拉克的时分来不及考虑复用,代码难复用导致之后的需求还要继续写许多的代码。

一点点堆集起来的大狼播量的代码又带来了安排和风格一致性等问题,最终构成了一个迈腾价格新功用根本靠拷的留传体系。

3.5.还有吗

烂代码还有许多种类型,沿着功用-功用-可读-可测验-可扩展这条道路走下去,还能看到许多匪夷所思的比方。

那么什么是烂代码?个人认为,烂代码包含了几个层次:

  • 假如仅仅一个人保护的代码,满意功用和功用要求倒也满足了。

  • 假如在一个团队里作业,那就有必要易于了解和测验,让其它人员有才能修正各自的代码。

  • 一起,越是处于体系底层的代码,扩展性也越重要。

所以,当一个团队里的底层代码难以阅览、耦合了上层的逻辑导致难以测验、或许对运用场景做了过多的假定导致难以复用时,尽管完成了功用,它依然是坨翔相同的代码。

3.6.够用的代码

而相对的,假如一个工程的代码难以阅览,能不能说这个是烂代码?很难下界说,或许算不上好,可是能说它烂吗?假如这个工程从头到尾只要一个人保护,那个人也保护的很好,那它好像就成了“够用的代码”。

许多工程刚开端或许仅仅一个人担任的小项目,我们关怀的要点仅仅代码能不能顺畅的完成功用、准时竣工。

过上一段时刻,其他人参加时才发现代码写的有问题,看不了解,不敢动。需求方又开端催着上线了,怎样办?只好小心谨慎的只改逻辑而不动结构,然后在注释里写上这么完成很ugly,今后了解内部逻辑了再重构。

再过上一段时刻,有个类似的需求,想要复用里边psp游戏下载的逻辑,这时才认识到代码里做了各种特定场景的专用逻辑,复用十分费事。为了赶进展只好拷代码然后改一改。问题解360行车记录仪决了,问题也加倍了。

简直一切的烂代码都是从“够用的代码”演化来的,代码没变,运用代码的场景发作变了,本来够用的代码不符合新的场景,那么它就成了烂代码。

4.重构不是韩竺全能药

程序员最喜爱跟程序员说的大话之一便是:现在进展比较紧,等X个月之后项目进展宽松一些再去做重构。

不能否定在某些(极端有限的)场景下重构是解决问题的手法之一,可是写了不少代码之后发现,重构往往是程序开发进程中最杂乱的作业。花一个月写的烂代码,要花更长的时刻、更高的危险去重构。

从前经历过几回深恶痛绝的大规划重构,每一次重构之前都是找齐了组里的高手,开了无数次分析会,把组内需求悉数暂停之后才敢开工,而重构进程中往往哀嚎遍野,简直每天都会出上许多意料之外的问题,上线时也简直必定会出几个问题。

从技能上来说,重构杂乱代码时,要做三件事:了解旧代码、分化旧代码、构建新代码。而待重构的旧代码往往难以了解;模块之间过度耦合导致牵一发而动全身,不易操控影响规模;旧代码不易测验导致无法确保新代码的正确性。

这儿还有一个中心问题,重构的杂乱度跟代码的杂乱度不是线性相关的。比方有1000行烂代码,重构要花1个小时,那么5000行烂代码的重构或许要花2、3天。要对一个失掉操控的工程做重构,往往还不如重写更有功率。

而抛开详细的重构办法,5200,关于腐朽的代码,德国牧羊犬从获益上来说,重构也是一件很费事的作业:它很难带来直接获益,也很难量化。这儿有个很有意思的现象,根本关于重构的书本无一例外的都会有独立的章节介绍“怎样红警3向boss阐明重构的必要性”。

重构之后能进步多少功率?能下降多少危险?很难答上来,烂代码自身就不是一个能够简略的规范化的东西。

举个例明华堂子,一个工程的代码可读性很差,那么它会影响多少开发功率?

你能够说:之前改一个模块substitute要3天,重构之后1天就能够了。可是怎样应对“不便是做个数据库操作吗王瑞儿为什么要3天”这类问题?烂代码“烂”的要素有不确定性、开发功率也因人而异,想要证明这个东西“的确”会添加两天开发时刻,往往反而会变成“我看了3天才看懂这个函数是做什么的”或许“我做这么简略的修正要花3天”这种神经病才会去证明的出题。

而另一面,许多技能担任人也认识到了代码质量和重构的必要性,“那就重构嘛”,或许“假如看到问题了,那就重构”。上一个问题解决了,但实际上关于重构的价值和收益依然是一笔糊涂账,在没有分配给你更多资源、没有清晰的方针、没有详细办法的情况下,很难幻想除了有代码洁癖的人还有谁会去履行这种不可思议的使命。

所以往往就会构成这种局势:

  • 不写代码的人认为应该重构,重构很简略,不管新人仍是白叟都有职责做重构。

  • 写代码内行认为应该早晚应该重构,重构很难,现在凑合用,这事别落在我头上。

  • 写代码的新手认为不出bug就谢天谢地了,我也不知道怎样重构。

5.写好代码很难

与写出烂代码不同的是,想写出好代码有许多条件:

  • 了解要开发的功用需求。

  • 了解程序的运转原理。

  • 做出合理的笼统。

  • 安排杂乱的逻辑。

  • 对自己开发功率的正确预算。

  • 继续不断的操练。

写出好代码的办法论许多,但我认为写出好代码的中心反而是听起来十分low的“继续不断的操练”。这儿就不展开了,留到下篇再说。

许多程序员在写了几年代码之后并没有什么出息,代码依然烂的让人不忍直视,原因有两个首要方面:

  • 环境是很重要的要素之一,在烂代码的熏陶下很难了解书法培训班什么是好代码,知道的人大部分也会挑选趁波逐浪。

  • 还有个人性情之类的说不清道不明的主观要素,写出烂代码的程序员反而都是一些很好共处的人,他们往往酷爱公司联合搭档和蔼可亲作业勤勤恳恳–仅仅代码很烂罢了。

而作业几年之后的人很难再压服他们去进步代码质量,你只会重复不断的听到:“那又有什么用呢?”或许“从前便是这么做的啊?”之类的说法。

那么从源头下手,进步招人时对代码的质量的要求怎样样?

前一阵面试的时分添加了白板编程、最近又添加了上机编程的标题。发现了一个现象:一个人作业了几年、做过许多项目、带过团队、发了一些文章,纷歧定能代表他代码写的好;反之,一个人代码写的好,其它方面的才能一般不会太差。

举个比方,最近喜爱用“写一个代码行数计算东西”作为面试的上机编程标题。许多人看到标题之后榜首反映是,这道题太简略了,这不便是写写代码嘛。

从实际效果来看,这道题辨认度却还不错。

首要,标题满足简略,即便没有看过《面试宝典》之类书的人也不会吃亏。而标题的扩展性很好,即便提早知道标题,合作不同的条件,能够变成不同的标题。比方要求按文件类型计算行数、或许要求进步计算5200,关于腐朽的代码,德国牧羊犬功率、或许计算的一起输出某些单词呈现的次数,等等。

从调查点来看,首要是根本的树的遍历算法;其次有必定代码量,能够看出程序员对代码的安排才能、对问题的笼统才能;上机编码能够很简略的看出应聘者是不是好久没写程序了;还包含关于程序易用性和功用的了解。

最重要的是,最5200,关于腐朽的代码,德国牧羊犬后的结果是一个完好的程序,我能够依照日常作业的规范去点评程序员的才能,而不是从十几行的函数里意淫这个人在日常作业中大约会有什么体现。

但即便这样,也很难拍着胸脯说,这个人写的代码质量没问题。究竟面试仅仅代表他有写出好代码的才能,而不是他将来会写出好代码。

6.失望的结语

说了那么多,定论其实只要两条,作为程序员:

  • 不要奢求其他人会写出高质量的代码

  • 不要认为自己写出来的是高质量的代码

假如你看到了这儿还没有损失期望,那么能够等待一下这篇文章的第二部分,关于怎样进步代码质量的一些主张和办法。


END



>>>>>> 加群沟通技能 <<<<<<


评论(0)