很久以前写过一篇较为幼稚的文章《“再论"业余"和"专业" ----致力职业化 提高成功力》,曾经引来了许多许多评论。时隔一年,这件事带给我的思想上的冲击已经忘却了,不想又被一个名为“Ferry的思想碎片”的blog钩起。它总算是保存了一点当时类似于《功夫》斧头帮百人大战的混乱场面的精彩言语。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
现在你从http://www.csdn.net/Develop/article/21/21289.shtm已经找不到当年的成千上万篇评论了。所以只能从也不复存在的“Ferry的思想碎片”的Badu缓存中找回那些值得一再回味的经典评论,特别是CSDN软工版版主o6z的留言。下面是Ferry从史海打捞出的摘要:
“这一逛成了无敌深渊。
感觉文章很混乱,通篇仅是强调注释、文档的重要性。后面引用weinberg的话,几乎所有共享软件都是垃圾。hoho~。麻烦肯定要来了。最后突然发现文章作者是科大的,wk~。
文章看完了,进度条却只在1/4处,而且是最小的。看来文章又引来了滔滔江水。
很快被ozzzzzz的文字所吸引。也许是赞同他的观点,也许是他的话很绝但又很精彩,也许是他后来的话很有趣。下面将他的话摘录下来(其中有段gigix的话):“
ozzzzzz(2003-9-28 16:07:05)
我不知道作者是谁 不过我想他很业余 作者最好看看介绍敏捷方法的书
在这里我只是想告诉作者 最优秀的编码绝对不会有注释 最优秀的工程的文档数量总会是最少的
至少作者要明白代码的可读性是说代码本身是不是容易被阅读 而不是说你加了多少注释
不管是谁 不管水平多高 如果你的一段编码必须要用注释才可以解释清楚 必须要文档配合才可以被人明白 那么你最好马上就开始重构 这一点作为一个业余的编程者是很难理解当一个专业编程者在面对大段的注释时的感觉
不理解要保持代码和文档的同步是要付出都大的代价 因为业余的就是业余的他们只是爱好 不会去考虑成本
软件工程是专业者的经验学科而不是什么CMM之类教授的学术研究成果 所以你才会看到人件得作者在说CMM是软件公司的耻辱
就如同作者给我们的一样 建议作者多看看最近几年软件工程的书 多注意软件工程的最新方法 而不是软件工程学的发展
ozzzzzz(2003-9-28 22:45:52)
考虑一下这样的情况 60左右个文档大概40万字 2万行代码 你需要保持他们绝对的同步 成本 成本你说你考虑了成本 就是考虑到成本 所以你的文档才必须尽可能的轻量化
看看Hibernate和junit 不过那里似乎到处都是/** 而据说CASE是最好的程序员 因为它们生成的代码写的/**最多
经过大量的实践以后XP被大多数方法学者所承认既便是最反对它的学者也承认在某些场景下它是非常有效的方法 不过你没有参加这样的实践 因为这些实践都是专业人员才可以参与的实践 业余的受不了那么严格的纪律 对了还忘了告诉你XP 没有什么新东西 它们只是一些陈旧方法的组合 当然这些方法都比你的所谓软件工程历史悠久的多 比如结对编程你就可以追溯到人类出现在最早阶段
你真的同意我说的你应该重构的话吗 我看你未必
只要学过软件工程的人就知道要写注释和文档
但是只有理解软件工程的人才知道要把注释和文档减少到最少
而只有有丰富软件工程经验的人才知道怎么才可以做到
不管你在什么样的公司 作什么样的工作 有什么样的职位 你都是一个业余的程序员因为你的方法是业余的 手段是业余的 观点也是业余的
哦 最重要的我到忘记告诉你了 Hibernate和junit都是GPL的 当然sourceforge.org中死去了那么多项目 可惜商业软件死去的数量也不少 而这一切在你这个业余的程序员的角度看不到全景
ozzzzzz(2003-9-29 11:21:09)
flyfreely
文档产生的目的是什么 大家思考过这个问题吗
1 首先 我觉得程序员的英语水平不能是加入注释的借口 如果要符合中国人的习惯 请去使用汉语编程工具 或者干脆就自己写一个不编辑器 这样你的代码中可以完全是汉语
2 哦 你的问题让我回到了以前那个美好的年代 那个时候我还年轻 z80 6502 学习机 书写难于被看懂的代码是水平的象征汇编是你唯一的编程语言 回忆过去真的美好
但是实际上我不知道你是不是认为 一个程序中真正需要性能优化的只可能是很小部分 而这些部分只可能存在于细节上 只可能是模块中的一个影响性能的关键部分而最为重要的是性能的影响基本上不会带来程序结构上的调整 而你是不是要对细节问题都说明清楚呢 我看这是一个策略问题 我觉得很多时候未必要对所有的细节都说明清楚 否则的话你的文档就会过于繁琐不利于阅读 而且我可以告诉你如果不是为了让人看不懂 即使汇编也可以很清楚 很明白 例如你有行号 有过程名 有宏名 这些都是你阅读汇编代码的线索
3 工具可以产生文档 但是你不要忘记文档是给人来阅读的 不是给机器阅读的 而工具产生的文档的一个特点就是过于繁琐 这是文档最应该避免的缺点 而为了保持一切的同步 CASE工具经常向代码中添加该死的注释 所以你可以看到很多人告诉你 不要使用文档生成工具
其实你应该看到 我说的是没有注释 和最轻量的文档 当你遇到一个新项目的时候 一个简单需求说明让你明白项目的背景 一个程序概要说明 让你理解了程序的结构而你保持的在性能优化前的代码 让你知道那些被优化的部分到底原来是什么
其实很多人以为有了文档就可以解决它们的问题 而不知道有了文档会带来的问题
ozzzzzz(2003-9-30 0:28:56)
嘿嘿 其实我之所以说你业余 其实本义在于从根本上否定你对GPL的看法 也顺便发挥一下敏捷的看法
不过说回来 国内对于文档的重视程度确实很差 现在很多人开始重视这个问题 可是这个重视就和软件工程刚在美国兴起的时候的情况一样 似乎越详细就越好 但是其实文档和注释的作用在于给人阅读一个轻量化的重点分明的文档要比一个事无巨细 包罗万象的文档好的多 而代码的自说明自文档的尝试一直没有停顿 ADA的一个巨大的优势就是在这个方面做了很好的尝试而模式的产生 又使面向对象的程序结构更加清晰 但是我想我们不可能马上成为一个优秀的代码编写者 这个时候你还是写一些注释的好 可是你必须要明白注释只是解决你暂时的问题而文档的结构的清晰才是解决问题的根本
对于XP的实施 我看还是要慎重 这到不是说XP有什么不好而是在于国内从事XP过程的顾问太少 在没有专业教练参与的情况下 实施任何一种方法都是很有风险的 可是国内任何方法的过程顾问都很少所以从这一点来说XP的风险和别的方法比较起来也未必就大 当然如果你有充足的¥ 使用RUP也很好 至少你可以找到专业的顾问
但是不管怎么样提高自己的设计和编码水平是必须的 这是基本功
而说到贵族化的编程 我想外科手术式的团队要比一大群水平低等的程序员组成的团队效率高的多 这一点在人月中也有很多阐述 我就不多说了
我想看看定级程序员的代码对我们大家都有好处 不知道我说的junit和Hibernate代码对你们有没有所提示 虽然它们都是JAVA写成的 但是我想只要你有些编程经历即使不懂java也会看明白
ozzzzzz(2003-9-30 2:24:15)
REFACTORING可以让你理解代码 而不需要你有什么注释 只要你真正的去重构了 了解设计意图可以看概要设计文档我认为写作注释和文档也要遵守面向对象的原则 让一样东西只在一个地方出现 很多人的设计意图不能被人很清楚的看明白 主要是概要设计作的不好 大家有多少还在沿用着-这个程序分为界面模块数据库接口模块 控制模块等等-这样的粗线条设计 设计概要设计要做到类的层次 要注明类中的方法
自然语言可以帮助人理解代码 当然也可以让人误解代码 为了使用javadoc这样的工具而添加的注释我认为其实是编码 因为你必须使用一种形式化的语言才可以完成这些工作 REFACTORING的目的在于减少代码中重复的部分也在于减少耦合 降低气味 这和你有没有注释没有关系 很多时候 由于有了注释会分散你的注意力 使本来十分相似的代码看起来却完全不同 而重构的最有力保证是建立完善的自动测试我想快速的迭代会让你十分熟悉你的代码 或者说你没有机会忘记那些代码 这和你有没有注释没有必然的联系
当然不是所有的人都可以写出不需要注释说明的代码 这需要很多的技巧和经验在你具备这些之前 你还是要写注释 可是具备这能力不是很困难 只要你学习模式 理解面向对象的方法 把耦合降低 提高内聚 只要你努力就可以做到
不是所有的程序员都具备了他们应该有的素质 而使他们能够很好工作的方法就是提高他们的素质 而不是交给他们功能强大的工具 嘿嘿 有工具的傻瓜还是傻瓜(大家去查查看谁说的这句话)
我想我以后还是用REFACTRING这个词比较好 避免使用重构让人望文生义
ozzzzzz(2003-10-1 10:23:24)
注释的问题其实是我同大家分歧的关键 所以先来说明
首先大家是否有完备的测试 测试可以用来说明代码的功能 这又是一个专业和业余的巨大区别 专业的开发应该是测试驱动 就好像我们在生产一个商业产品的时候要先制度它的质量标准并且是可测试的标准 例如色泽鲜艳这样的标准说明就不是很好 而没有可见斑点这个就好的多 如果你把你的编码也看作产品的化 就必须在开始的时候就制定测试标准和测试方法而测试同时也在说明你要完成的功能 同时测试的标准也会在以后的环境中发生变化 要符合你新添加的功能 这是你的根本保证
阐述了一些XP的观点 回到讨论中 我来回到 smartcard提给我的问题
首先我觉得他说的如果不熟悉协议就会看不懂 我觉得这种情况的出现就很有问题 他不懂这个协议他来看代码就可以明白协议了 我看不如让他直接去学习协议要好的多然后他又说如果一个鲁莽的人来修改 这又很又问题 鲁莽的人要么不看你的注释 要么看了也当没有看 而且即使看了也看明白了 但是鲁莽的人不会因为你的注释而不鲁莽 因为你不可能在注释中添加可以让人进入催眠状态的文字鲁莽的人就是鲁莽的人 只能让他们远离那些代码
如果那个鲁莽者修改了代码造成了麻烦怎么办 奇怪的问题 似乎你们不作版本管理 如果是这样我只能说你们确实很业余
后面的问题其实他说了一个我早就要阐述的问题 文档的详细程度是要符合你要面对的现实
但是作为他说的必须有详细设计文档才看明白代码的的论述 其实很有问题 如果这个详细说明是在代码前有的 那么我不知道你是不是可以做到你的设计就一定可以实现特别是在性能和环境要求严格的情况下 很多时候你要反复修改 反复优化 最后的情况是如果你的文档不变化 你的代码结构往往和它的文档距离有地球到冥王星那么远 而为了保持同步你必须要付出代价但是是不是就不需要详细设计文档了呢 我的建议是你不需要详细设计 但是详细设计文档你是需要的只是详细设计文档的来源不是详细设计 而是你的代码 我想很多人也是这样作的 只是我觉得这个文档应该改一个名字 叫代码结构说明
最后还有一个问题 这个问题我没有把握 有可能会是错误的想法 但是我还是要提出来
他说---“如果不写注释,仅看函数名字,对协议不清楚的人肯定不知道这个函数要做什么,输入是什么,什么样的输入是必须避免的,输出是什么。”
这里我想有一点我还有把握 就是必须对代码的输入作检测 看那输入是不是属于--必须避免--的那些类别 我想这是他本身的编程水平问题 不是我们要讨论的而我们都要注意的是 如果你没有明确的提示 你就不能知道输入的是什么 这是不是有一个函数的参数过于多的成分 如果是这样 我想这是设计风格简陋的问题 应该改进他的设计使输入的参数减少 也就是要REFACTORING那些代码 可是我想作者使用的可能使C 我不知道如何在C下REFACTOR 但是我也试着提出一下方法例如 你是不是可以使用结构了组合你的输入参数 同时把大函数划分为小函数 由于我没有在c下实施refactor的经验 所以只能凭想象来解决你的问题 可能会是错误的看法
gigix(2003-10-1 12:19:10)
看o6z在这边讨论了这么久,忍不住也想说两句。楼上有位同志说“我不相信真正的‘职业’程序员的代码是没有注释的”,不过事实的确如此:大多数职业的Java程序员在正常的工作中从来不写注释。以我的工作为例,只有两种情况下会写注释:(1)还有5分钟就要下班,但一小块代码还没写出来,又懒得写一个测试用例来标注它,于是放一行TODO的注释;(2)项目结项之前,给每个方法补上JavaDoc。其实,这两种工作方式也并不是那么很“职业”,只不过是权宜之计。
在一个程序中,注释起怎样的作用?在我看来,第一,用注释说明一块代码的作用;第二,提醒自己(或者别的程序员),这里还有什么东西没做完;第三,用于自动生成某些文件,可能是EJB部署符、Hibernate映射描述之类的东西。显然,第三种用途本身也应该是“编程”的一部分,在此不讨论。而前面两种用途都是不那么“职业”的。如果一块代码需要注释才能看懂,那么就应该重构它,让它看上去更清晰;如果希望让别人知道一个模块的用法,就应该在单元测试里加上一个用例;如果还有什么需要做的事情没做,也应该在单元测试里加上一个用例,这个用例只有在需要做的事情都做完之后才能通过,这样明天早上你运行一次单元测试,就会发现这里还有些事情没做。而注释,它本身就是一种bad smell,它的出现就意味着你需要重构或者增加单元测试。
楼上还有一位说“文档是软件设计的‘契约’”,错了,软件设计的契约只能是接口,不多也不少。如果你的代码违反了文档的规定,没有人会给你报错;只有当代码违反了接口时,编译器或者别的什么东西才有可能提醒你。Java并没有一个很好的Design by Contract机制,但是——在最原始的情况下——至少你可以用assert来检验一个方法的前置条件和后置条件。举个例子:如果你在文档里写“输入的username不得为null”,但别人就是不遵守这个规定,你怎么办?你就等着在web页面的最顶端或者是log文件里发现一个NullPointerException吧,它不会给你太多的调试信息。而如果你在方法的开始处写上assert(username != null),如果有个冒失鬼传了null给你,你会马上看到一个AssertionError,里面清楚明白地写着“Xxx.xxx方法:username不得为null”。如果要说“职业素养”,我认为这就是最重要的职业素养:它把你(或者你的同事)找到问题所在的时间从10分钟缩短到5秒钟。
ozzzzzz(2003-10-1 14:55:47)
看到了gigix 真的有意思见鬼的书还是没有出 只是看到了模式之乐
我忽然想到了德克萨司的正义 律师说--我没有狗(有人控告你的狗咬了他) 现在我作的就是玩没有狗的游戏 我为了反驳作者对GPL的蔑视 不是按照普遍的同他直接对抗的手法 而是去论证他自己就很业余 效果实在太好了 最后的讨论绕开了GPL是不是有价值的这个低级命题 开始讨论对大家都很有帮助 并且会有深刻影响的注释和文档问题 这是我乐意看到的
我也有些忧虑 似乎很多的朋友对于一些很热点的概念完全不了解 这些本来应该是任何一个职业面向对象语言的程序员必须掌握的职业手段 比如重构 好在gigix翻译了REFACTORING 而马上 模式精解 就会出版 我想对我们大家都会有帮助
刚看了几页重构 说实际的 我不喜欢候先生的语言风格 主要是因为我不喜欢他的有古典语言倾向的书写方法 这样的方法让我的阅读没有一种愉悦的感觉 而虽然我的英文不是很好但是看原版的时候 还是有心领神会的感受 这种感觉是那么重要因为他让我那么投入 那么容易理解作者的想法 这就是一种美 这样的美是在你看 阅微草堂笔记 的时候感到的在你看煮就论英雄时候可以感到的 我需要这些愉快的感觉
在你编码的时候也需要这些感觉 同时让别人阅读你的编码的时候也要有这些感觉 排除那些打扰你的东西 不要打断你的编码 深入编码之中 享受编码的乐趣 也让别人享受你可以享受到的乐趣
很多时候你可能会看到有这些感觉和没有感觉差不多 但是如果你把他们放在一个现实的复杂环境下 在一个比较长的时间段 就会看到这些感觉的宝贵 就会知道愉快带来效率
而写作中我们的那些感觉很容易丢失 而似乎西方人却很会保持那些感觉 同时你也可以看到东西方的写作手法很不同 似乎西方人写作没有一个主题写到什么地方就是什么地方而他们只有一条线索 把那些碎裂的小块串连起来 这个线索往往就是作者的思路 而我们的做法往往是先有一个主题 然后就围绕这个主题开始论述观点一二三 我们没有那个线索但是我们有一个主题 其实在看一个小文章的时候 用主题的方法组织文章会更好 而用线索会很差 可惜我们大多数时间写作的都是大文章 这个时候你的主题往往会被细节所淹没而总是强调你的主题会让人感到厌倦 所以还是用线索的方法 最后让主题浮现出来 其实我们的古人很早就明白这些道理 所以你看八股文出现以前的文章就往往会有所不同
编程也需要考虑这个问题 考虑你是要主题还是要线索 要主题你就必须有大量的文档等手段要线索就必须有重构和自动化测试这样的能力 但是让我选择我会选择能力 因为那些手段总是不可靠的 而且使用那些手段一样需要能力 也是需要学习掌握的 而这样作的代价暂时来说未必就会小就更不用说长久了
而传统软件工程的思想也一样 似乎软件的成功建立在程序开发者的能力强大是一种罪恶 需要用一种过程以使一些水平低等的人组成一个团队 并且可以让他们可以一起工作这样可以带来低成本和高成功 而最近几年就如同你在人月和人件中看的 主流的观点已经发生了变化 人的因素被认为是最重要的 不过这个时候对传统软件工程的否定不如说是对传统这个词的否定 因为人们从新发现 软件工程在过去一些人在使用一些反传统的方法 因为那些所谓的软件工程学者只是肤浅的学习了传统行业的做法 他们根本就认识不到程序员是生产者其实也是生产工具 传统工程方法都是建立在以工具为中心的体系下 而唯独软件工程要建立在以过程为中心的体系下 现在对人的重视只是回归了传统 回归了工程 回到了人类自产生以来就开始作事情的普遍方法
ozzzzzz(2003-10-2 9:48:33)
我再来给gigix补充一下契约是不可变更的 如果设计是契约 那么设计也就不可变更 而保证设计的正确必须要对设计作大量的测试 可是测试不是评审 必须要对现实的产品进行检测才可以 而既然你已经有了产品了你还需要另外建造另一个产品吗 所以你可以看到设计只是最初的想法 随着编码的进行会发现很多的问题 你为了解决它们就必须作一些改变设计想法的编码
而对于swinging的说法 我想起来管理来源于恐惧
现在我又要抛出敏捷方法下的最重要的部分 使用小迭代增量开发你的产品 也就是要把你的生产结果不断的提交你的用户 而这就要求必须把客户的需求划分成很小的部分也就是在一个迭代可以完成的部分 你不能让客户和领导等待的太久 让他们等待几个月才知道你作的怎么样 你设身处地的想一想 你也会感到恐惧 而小规模的提交 让他们看到最近你工作的成果是可以运行的那是对他们最大的安慰 所以你必须保证它的需求完成情况是可见的 同时并且要可以让客户看到这些可见的结果是可以工作的
其实在我看来敏捷方法的核心就是小迭代 高频率提交 这是缓解管理压力的最有效途径
而文档只是给客户和领导一些暂时的安慰 他们只是感觉似乎你是在为他们工作 你的工作似乎是有了进展 其实他们还有很多的忧虑 文档不可能告诉他们那些东西是可以工作的是有效果的 而文档带来的成本他们其实也是很明白的知晓的 他们急切的想知道的你们工作的结果 而不是文档
ozzzzzz(2003-10-8 12:28:37)
zhengyun_ustc
其实你是在说没有功劳 也有苦劳中的那个苦劳的问题
但是我想维持代码的纯洁性是对投资者最好的保护 如果你有时间去写那些注释 不如干些别的更加有好处的事情 而很多时候多做的事情就是你作错的事情
我是在北京的 我想我身边的很多朋友也同意我的观点 这些和是不是在国外没有关系
ggw
前期的文档 我想是指需求说明书 这个文档我觉得也是会有一个逐步完善的过程很少有一步就得到最终版本的事情发生 当然要让客户接受这种迭代的想法也是有困难的 但是我想他们不会看不到可以修改需求对他们的利益是非常有好处的 只是他们不希望为你给他们修改的权利付出更多的代价
关于 900126转贴的那些文学性的文字我想没有必要在这个严肃的话题中讨论
ozzzzzz(2003-10-9 15:27:59)
我很早就在思考规模对生产方法的影响的问题
我有一个看法 这个看法和传统的软件工程理论完全不同 在我看来越是重型的方法 越是规模巨大的项目 也就越是依赖项目中有水平高超并且可以起到决定作用的超级人才当然采用这样方法的组织也更有资金可以找到那样的人才 其实我想大家最应该记住的是那那句话你多做的那些事情就是你做错的那些事情
MDA现在还不是现实 而且在我看了uml一样是一种语言一样是一种编码
看了那个周的访谈觉得很奇怪 我觉得软件工程是很基础的 没有那么高的门槛 而同时rose和uml不代表就是软件工程 uml只是语言 而rose只是一直工具
”