`
wangxiaohigh
  • 浏览: 1462924 次
文章分类
社区版块
存档分类
最新评论

所信奉的编程哲学

 
阅读更多

陆陆续续看完了《代码大全》、《重构》、《代码整洁之道》、《程序员修炼之道》以及《The Art of Readable Code》,获益匪浅。下面就分享几条我赞同并信奉的编程哲学,顺便废话几句。

本文适合有一定编程经验的读者阅读,高手请轻喷:)

 

代码是写给人看的(Coding for Reading)

 

请先思考,评价一段代码优劣最重要的标准是什么?

有个著名的图,相信大家都见过,讲的是Code Review时被骂WTF的次数越少,代码的质量就越高。这虽然有点无厘头,但是却不无道理。

《The Art of Readable Code》中告诉我们,评价一段代码的质量的最佳标准是可读性,即别人理解代码意图所需要的时间。

可读性有什么用,我写出一段代码,能完成目标,能通过测试不就行了吗?

不管你是团队开发,还是一个人单干,只要项目还在运作,代码总是要有人来维护的。如果有一天你不在或者离开了,别人应该能很轻松的看懂你的代码,而不是猜来猜去,最后还要来问你,甚至弃用整段代码重新再写。作为一个负责任的开发者,应该尊重自己的劳动成果,也尊重别人的时间。

当你写下一段代码时,脑子里有清晰的逻辑(比如这里必须这么做,因为……这里不能那么做,因为……)。而别人看这段代码时,脑中是一片空白(这个变量是干什么的?为什么要多加一层判断?这个数为什么是 2 不是 3 ?),除非能完整复现你当时脑中的逻辑,否则就不能理解这段代码。

所以我们应该做的是,把写代码时脑中想到的逻辑的每一个细节,尽可能地写到代码以及注释中,从而帮助后来的阅读者快速复原整个逻辑。简单来说可以有以下的方法:

用常量代替魔术数

在一段代码中出现 if ( level > 3 ) ...的时候,也许你会想:为什么是 3 不是 4 呢?这就是所谓的魔术数。通过上下文也许你可以判断出这个 3 是指最高等级,但是可能这段代码中 3 出现了好几次。你会迷惑:它们是不是都是一个意思?当我要把最高等级改成 4 的时候,是不是应该修改所有的 3 ?

如果代码的作者定义一个常量MAX_LEVEL = 3,同时还有一个常量USERS_PER_PAGE = 3,并在不同的地方使用不同的常量,就不会有这样的混淆了。

使用富含信息的类名、变量名和函数名 

doit();
$return = $str2 . ':' . $str3;
return $return;

 这样的代码,简直就是人工混淆过的。你会发现这些代码根本不能帮助你理解代码的含义。

也许你该写成这样? 

handleError();
$error_message = $error_code . ':' . $error_status;
return $error_message;

在注释中说明一段代码存在的原因,而不是行为

$('#item').html(''); //清空item的内容

 这样的注释有意义么?用自然语言重新描述一次代码的行为,除了徒增维护时的工作量外没有任何价值。你应该说明为什么这样做,以供别人看到这段代码时明白你是怎么想的,并决定如何修改或者对待这段代码。 

$('#item').html(''); //先清空容器的内容,否则可能导致内容重复

 

写得越少越好(Less is More)

 

这个规则的使用性太强了,我简单说说减少逻辑层次和缩小函数体这两个方面吧。

减少逻辑层次

当逻辑层次超过三层时,理解这段代码的难度会急剧上升。我相信谁也不喜欢去读一个n层括号的表达式,或者面对n层缩进的条件判断/循环。

对于复杂的表达式,通过提取中间变量来降低表达式的逻辑层次,保证每个表达式的逻辑层次不超过二层。

对于多层条件判断,大多数情况可以用防御式编程将其简化成单层的条件判断,尽早return或者exit。此外,单行的if-else判断往往可以用三元操作符替换。如果判断实在太多,也许你该重新设计一下结构了。

缩小函数体

记得有一位语言的创始人说过:“我不喜欢比我的头还大的函数”。

事实上,大家都喜欢短小精干、一眼就能看到底的代码。简洁明快的代码有助于别人迅速理解代码的意图,也方便快速定位问题。如果一个函数要滚动屏幕才能看全,那你往往要不断地来回滚动,并强迫自己记住一些信息,再返回去看另一部分,这样做会非常累。

随着函数体不断膨胀,理解它所需要的时间随之增加,出错的几率也会大大提升。而且越大的函数,可维护性和复用性越差。当部分代码逻辑需要修改时,不能快速定位到要修改的位置,也难以确定函数体其他位置是否也需要对应的修改。

当函数尺寸失控时,首先要想到的是,有没有其他方法,用更少的代码完成这个任务?能不能用正则表达式?能不能用查表法?有没有内置的库函数可以利用?

面对一个无法再简化的流程,将其拆分成细粒度的步骤,将每个步骤的相关代码分离出来,提取成子函数,再给子函数起一个漂亮的名字。这样可以降低理解主流程的难度,在做修改时也可以通过函数名快速定位,而且因为相关的代码都在一起,不容易漏改。

也许你会怀疑调用函数所造成的性能损失,我想说现在这个时代,手机都马上四核了……

 

不要重复(Don't Repeat Yourself)

 

看过《重构》一书后,我看到代码中任何重复的地方都如见眼中钉。

重复是万恶之源,当你发现你在对代码的不同部分进行同样的修改时就要警惕了。改的地方越多,就越可能出错。也许忘了改一个地方,也许错改或者删除了周边的代码……永远不要让这种事情发生!

将重复的代码提炼成子函数 

$('#count').text( + $('#count').text() + 1 );
...
$('#count').text( + $('#count').text() + 1 );
...

 如果一段相同的代码出现两次,基本上你还会第三次用到它,所以很有必要将其提炼成子函数。这样不仅可以减少代码量,还可以降低维护的难度。

复制代码
countPlusOne();
...
countPlusOne();
...
function countPlusOne() {
    $('#count').text( + $('#count').text() + 1 ); //以后修改只用改这里就好了
}
复制代码

如果有几段代码很相似,往往可以提取其共性逻辑,使用不同的调用参数进行区分。

复制代码
countChange( +1 );
...
countChange( -1 );
...
function countChange( change ) {
    $('#count').text( + $('#count').text() + change ); 
}
复制代码

 用循环减少重复 

$item[ 'id' ] = $_POST[ 'id' ];
$item[ 'name' ] = $_POST[ 'name' ];
$item[ 'mail' ] = $_POST[ 'mail' ];
$item[ 'qq' ] = $_POST[ 'qq' ];

 如果有大块逻辑雷同只有一两个地方更改的代码,往往可以用循环来解决:

foreach ( array( 'id', 'name', 'mail', 'qq' ) as $key ) {
    $item[ $key ] = $_POST[ $key ];
}
7
5
分享到:
评论

相关推荐

    编程知识库工具 非源码

    该程序仅献于信奉“好记性不如烂笔头”的朋友们! 记性超好!过目不忘者!不需要该程序! 程序作用: 用于大家储存编程和计算机方面的 问题和解决方式!便于大家在查询方便! 程序说明: 大家可根据自己的需要自行...

    曾国藩一生信奉16个字.docx

    【曾国藩一生信奉16个字】的文档揭示了曾国藩成功的人生哲学,这些原则对于个人成长和领导力提升具有深远的启示。以下是根据文档内容详细解析的六个核心知识点: 1. **坚忍**:坚忍是面对逆境时保持不屈不挠的精神...

    高质量C++编程指南

    PS:附上林锐博士的所述前言 软件质量是被大多数程序员挂在嘴上而不是放在心上的东西! 除了完全外行和真正的编程高手外,初读本书,你最先的感受将是惊慌:“哇!我以 前捏造的 C++/C 程序怎么会有那么多的毛病?”...

    高质量C++编程指南.zip

    前 言 6 第1章 文件结构 11 1.1 版权和版本的声明 11 1.2 头文件的结构 12 1.3 定义文件的结构 13 1.4 头文件的作用 13 ...我曾经也这样信奉,并且希望自己成为那样的“真正”的程序员,结果没有得到好下场。

    2019_2020学年高中政治第1单元生活智慧与时代精神第1课美好生活的向导第2框关于世界观的学说课堂训练新人教版必修4

    例如,认为“命由天定”的人可能会在遇到困难时选择消极应对,而信奉“人定胜天”的人则会积极面对挑战。这表明一个人的世界观决定了他处理问题的方法和态度,即世界观决定方法论,方法论又体现世界观。 接着,题目...

    想象龙-信奉-Arduino封面-项目开发

    标题“想象龙-信奉-Arduino封面-项目开发”暗示了一个创新的电子音乐项目,利用Arduino控制器来重现流行歌曲“信奉”(Believer)的封面版本。在这个项目中,开发者可能通过编程Arduino来控制推挽螺线管,这是一种...

    数学沉思录

    蜚声世界的科普名家Mario Livio,回顾了千百年来人类所进行的深层次思考,试图从哲学角度阐释数学的本质,揭示数学与物质世界和人类思维之间的紧密联系。从信奉万物皆数的毕达 哥拉斯、刀斧之下依然从容演算的...

    论文研究 - 护士护理方法(NCAp):将差异与阿拉伯世界的伊斯兰信奉患者联系起来

    在护理专业中,护士被多元文化护理能力所吸引,这使护士能够适应并牢记他们如何提供和配合他们的护理工作。 这将使非穆斯林护士在与穆斯林患者的交流方式和交流方式上必须认识并足够敏感。 目的:该研究旨在确定在...

    浅析《老实人》中的象征与隐喻

    综上所述,《老实人》通过对象征与隐喻的巧妙运用,传递了深刻的社会批判和哲学思考,同时展现了伏尔泰独特的文学探索和创作才能。通过这些文学手法,伏尔泰不仅揭示了18世纪欧洲社会的种种矛盾和问题,也向读者展现...

    人文精神的内涵与实践方向.docx

    西方哲学家普遍信奉“知识即德行”,在探求真理的过程中,不问实用,只为真知。相比之下,中国哲学更注重德行与知识的统一。培养好奇心和认真态度,鼓励独立思考和批判性思维,是教育的重要目标,也是促进科学和哲学...

    java8集合源码-usefullinks:有用的编程链接

    有用的编程链接 Java: 精选的 Java 框架、库和软件的精选列表。 Java 对象内部结构 (Shipilev) 在 JVM 厨房中烹饪字节码 Java 性能案例研究 垃圾收集器工作描述(公爵,倒垃圾) 用于在 JVM 上启动和开发 Java 应用...

    继父_csdn

    尽管这个故事并不涉及IT技术或者编程知识,但其内容所蕴含的人性光辉和生活哲学,对于任何想要了解人类行为、决策和情感世界的读者来说,都具有深刻的意义。这不仅仅是一篇关于个人经历的文章,它更是一本关于如何...

    Estruturas-de-Dados---UECE:达斯托斯一世的信奉达人一世

    在这个" Estruturas-de-Dados---UECE:达斯托斯一世的信奉达人一世 "项目中,我们很显然会深入探讨数据结构及其在Python中的实现。Python是一种流行的编程语言,以其简洁的语法和强大的库支持而闻名,特别是在处理...

    兰亭集序公开课.ppt

    《兰亭集序》是古代文人墨客的一篇经典之作,由东晋时期的书法家王羲之所作。这篇作品在文学和哲学上都有着深远的影响,它不仅展现了王羲之卓越的书法技艺,还表达了他对人生无常、生死观的深邃思考。在本次公开课中...

    12540 企业文化-企业文化简述(PPT 8页).ppt

    我国学者魏杰对它的解读是,企业文化是企业所信奉并付诸实践的价值理念,是企业生活中的核心原则。而泰伦斯·迪尔和艾伦·肯尼迪则认为,企业文化是一个企业所坚守的主要价值观,体现了企业的精神内核。 企业文化...

    东大22春《管理学原理》在线平时作业2-00001

    1.如果一个领导者决断力很强,而且信奉X理论,他很可能采取以下哪种领导方式()2.文化的特征不包括( )3.德鲁克指出企业是由他的______来定义的4.______是销售总额与库存平均价值的比例关系()5.为了激发员工内在...

    高二语文必修五第2单元古代抒情散文测试题及答案解析精选.doc

    4. 进步论的反思:现代人普遍信奉进步论,认为发展意味着进步,但这种观念在地球生态环境恶化的背景下受到质疑。现代文明的进步并未带来预想中的幸福,反而可能导致与自然的进一步疏离。 5. 诗人哲学与回归诗学:...

    安徽省芜湖市无为中学等三校2020学年高二语文上学期期末联考试题(无答案)新人教版.doc

    综上所述,这份试题的部分内容引申出的议题涉及哲学、文化、社会等多个层面,旨在引导学生思考现代文明对个人生活的影响,以及如何在现代社会中保持个体的自由与尊严。通过这样的试题,可以训练学生的批判性思维,...

    JavaScript 前端框架Web UI 解决方案源码.zip

    区别于那些基于 MVVM 底层的前端框架,却并非逆道而行,而是信奉返璞归真之道。准确地说,它更多是面向后端开发者,你无需涉足前端的各种工具,只需面对浏览器本身,让一切你所需要的元素与交互,从这里信手拈来。...

Global site tag (gtag.js) - Google Analytics