漂亮的代码漂亮的代码

  Ruby的创造者为《代码之美》撰写的文章标题是《代码如散文》。程序和散文有一些共性,首先是两者都必须有清晰的意图,散文内容是什么,想表达什么,程序的功能是什么,能做什么;其次两者在意图的表达上(功能的实现上)都依赖于写作的具体风格,编程的隐喻之一就是写作。你想表达的思想是好的,但是如果表达得难以理解,那么要把这个思想传播给读者将非常困难。代码被读和修改的次数是相当多的,因此一个很重要的观点就是你写的代码是给人读的,你需要考虑可读性的问题,归结于写出漂亮的代码。
   判断代码是否漂亮似乎没有什么国家标准,更没有国家免检。代码是写给人读的,从这个角度上看,如果一段代码能让人很容易地读懂,让人感觉心情愉快,修改起来也不费什么力气,这似乎就是漂亮的代码咯。那么显然,漂亮的代码的真正含义是帮助程序员感到快乐和提高生产率。有了这个指导性的方向,你可以从这么几个方面去努力写出漂亮的代码:简洁性、保守性、简单性、灵活性和平衡。
   简洁性,文中以Ruby和Java版本的Hello World入手比较,在Ruby和其他动态语言中,你所做的就是你想表达的:打印Hello World

print "Hello World\n"

换成java,哦,你先要定义一个类,这个类有个入口main方法,在main方法中调用System.out对象的println方法打印:

class Sample{
   public static void main(String []args){
     System.out.println("Hello World");
   }
}

我记的我初学java的时候就特别不理解为什么要定义一个类,为什么方法要static、args,而我仅仅想要的只是打印一个字符串,可语言硬塞给了我太多的概念:类、方法、入口、参数。这些额外的东西牵扯了太多的注意力,而往往却忘记了初衷是什么。因此在《unix编程艺术》一书中对OO的一个评价是:鼓励具有厚重的胶合和复杂层次的体系,大大降低了代码的简洁性和透明性,你无法一眼看出代码是想做什么的。OO的抽象能力很强大,因此在很多场景下是这种抽象能力的滥用,实现最简单的功能也是一定要有类,有类才有对象,有对象才有光:)而往往这些对象却非问题领域中的自然实体,而是某种胶合物,为了抽象而抽象。
   简洁同样意味着消除冗余。代码的重复是万恶之源,拷贝黏贴是滋生bug的温床,在重构概念如此深入人心的今天,这一点毋庸置疑。因此,谨记请DRY原则。语言级别的冗余可能是需要的,例如Ruby允许方法调用省略括号:

task :name=>:test
task({:name=>:test})

这两行代码想表达的意思一样,显然第一种方式更简洁,这种语言级别的冗余显然是有利于程序员的,尽管将实现的难度推给了语言的设计和实现者。
   漂亮代码另一个有争议的方面就是它的熟悉性,人们对于新东西的接受程度远没有想象中的高,大家都喜欢自己熟悉的东西而非全新的思考方式(嗯,极客例外)。这其实是Ruby一直鼓吹的最小惊奇原则的另一种表达。Ruby看来就是这么个保守的语言,他有很强大的OO能力,但是没有全然照搬smalltalk,他有FP的能力但是却没有让你惊掉下巴,他仍然遵循着古老的顺序、循环、选择的程序结构。
   简单性强调是减轻程序员的工作负担,语言和类库API的优化应当有利于使用者,将困难留给实现者。前面提到的语言的冗余性就是一例。程序的复杂性来源有这么几个:商业上基于推销热点而非实际需求考虑出发带来的“特性清单”、业务领域本身的复杂度、程序员的自傲心理,最根本在于软件的开发的复杂性。如果能将复杂的功能,用人人理解的简单代码表达出来,当然漂亮!
   简单并不意味着简陋,保守也不意味着死板。灵活性同样是代码漂亮与否的判断标准,是否隔离了变化点,是否拥有一定的扩展能力,是否无需借助工具的增强而实现某些巧妙的调用。同样以Ruby为例,open class和元编程给了内置你在语言级别的“工具”,你无需借助antlr、cglib等等类库去做一些看似复杂的东西。你将感受到编程的快乐,而非为了工具而去做一些违背本意的事情。灵活性可能是把双刃剑,过分的强调灵活性、可扩展性也可能带来复杂的代码,注意你的“炫耀”心理。
   最后要强调的是平衡,在这些因素之间做出平衡,我觉的吧,没有更多实践的经验想平衡这些因素是相当困难的,如果了解了平衡的艺术,也许算是透出那么点“编程的艺术”的味道。Matz一直强调的一点是编程的乐趣,如果没有乐趣,我想我不会干这行,如果没有乐趣,我想我的工作效率将极度低下,从你认为是枯燥的工作中找乐子,存了这么个心理,你总能找出很多可以做的有趣事情,问题在于,你肯不肯做?

ps.加张图片,俺的blog国家免检

   文章转自庄周梦蝶  ,原文发布时间2008-10-09

时间: 2024-11-05 04:09:46

漂亮的代码漂亮的代码的相关文章

漂亮CSS+DIV导航菜单代码

提示:您可以先修改部分代码再运行 漂亮CSS+DIV导航菜单代码 Home Single Level Dropdown Dropline Flyout Support Contact 提示:您可以先修改部分代码再运行

统计有多少行JS代码和ASP代码

js|统计 计算当前文件夹中,有多少行JS代码和ASP代码,并且还可统计代码有多少字节有示例代码 [复制此代码]CODE:<% '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ '\\ '\\    来自 codeproject.com '\\    计算js和asp代码 '\\    修改 bluedestiny '\\    mail:bluedestiny at 126.com '\\ '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

小工具:计算当前文件夹中,有多少行JS代码和ASP代码,并且还可统计代码有多少字节

js|统计 计算当前文件夹中,有多少行JS代码和ASP代码,并且还可统计代码有多少字节 有示例代码 <%'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'\\'\\    from codeproject.com'\\    calculate code'\\    bluedestiny'\\    mail:bluedestiny at 126.com'\\'\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ opt

统计有多少行JS代码和ASP代码,并有多少字节

js|统计    计算当前文件夹中,有多少行JS代码和ASP代码,并且还可统计代码有多少字节      有示例代码      <%   '\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\   '\\   '\\ 来自 codeproject.com   '\\ 计算js和asp代码   '\\ 修改 bluedestiny   '\\ mail:bluedestiny at 126.com   '\\   '\\\\\\\\\\\\\\\\\\\\\\\\\

java与js代码互调示例代码

用到java和js方法互调,在用HTML5做跨平台应用开发时经常会用到,在这里分享一些自己在实际开发过程中的用法,希望对初学者有所帮助   在用HTML5做跨平台应用开发时,尝尝会用到java和js方法互调的问题,对初学者而言,可能会有点难,在这里分享一些自己在实际开发过程中的用法,希望对你有帮助: 首先是js代码调用java代码介绍: 复制代码 代码如下: public class CzingLBWebMain extends DroidGap { @Override public void

access代码-求这个邮件群发的代码,部分代码如下

问题描述 求这个邮件群发的代码,部分代码如下 Function Printf(ByVal theFormat As String,ParamArray Values())As Dim ResultString As String Dim Element As Variant Dim FormatLocation As Long If IsEmpty(Values()) Then 'raise an error End if ResultString= theFormat For Each Ele

模拟交换机查表功能-请大神补充里面的下拉框代码,主代码已有,自己电脑运行老是报错,谢谢啦!

问题描述 请大神补充里面的下拉框代码,主代码已有,自己电脑运行老是报错,谢谢啦! 请大神做好打包发q 1125485579@qq.com 这是文件链接http://download.csdn.net/detail/liu10231217/9326519 解决方案 50c就够找苦力,留下个邮箱坐等代码送上门.就算有人愿意帮你,你文件链接都懒得贴也是醉了. 解决方案二: 你还留什么q,干脆留个银行卡账户,看看有没有好心人给你捐点得了. 解决方案三: 没办法思密达!表示对自己这个专业很是头疼 解决方案

电脑断电代码的页面代码全没了

问题描述 电脑断电代码的页面代码全没了 我在工作写着写着代码突然公司断电,等来电了,我打开电脑我刚才写代码的页面代码全没了,不止是没保存的没了是保存的都没了,我写了好几天的啊!有没有大神能帮恢复一下? 解决方案 文件还在吗,打开没有代码了?如果是这样,不能恢复了应该

typedef struct-求大神找到下面代码中的代码的错误,并改正!

问题描述 求大神找到下面代码中的代码的错误,并改正! #include #include #include typedef struct { int a; int b; } DOUBLE_INT, *Double_int; Double_int a[4]; int main() { int i; for ( i=0; i < 4; i++) { a[i]->a = (i+1); a[i]->b = (i+1)<<1; } for ( i=0; i < 4; i++) {