﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-qixinkui</title><link>http://www.cppblog.com/qixinkui/</link><description /><language>zh-cn</language><lastBuildDate>Thu, 23 Apr 2026 19:48:31 GMT</lastBuildDate><pubDate>Thu, 23 Apr 2026 19:48:31 GMT</pubDate><ttl>60</ttl><item><title>【译】一篇 Dave Herman 讲软件开发周期阶段的帖子，涉及 艺术，工程，科学，抽象 框架 工具 这些内容</title><link>http://www.cppblog.com/qixinkui/archive/2011/10/28/159272.html</link><dc:creator>cingoli</dc:creator><author>cingoli</author><pubDate>Fri, 28 Oct 2011 07:53:00 GMT</pubDate><guid>http://www.cppblog.com/qixinkui/archive/2011/10/28/159272.html</guid><wfw:comment>http://www.cppblog.com/qixinkui/comments/159272.html</wfw:comment><comments>http://www.cppblog.com/qixinkui/archive/2011/10/28/159272.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/qixinkui/comments/commentRss/159272.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/qixinkui/services/trackbacks/159272.html</trackback:ping><description><![CDATA[<div><div>原文被墙，觉得该文其意不错，但其所指其实不是很明确，用语生涩啊...</div><div>=================================================================</div>http://calculist.blogspot.com/2007/09/science-and-engineering.html<br />Science and engineering<br />从 The Little Calculist 作者：Dave Herman<br /><br /><div>Joel Spolsky 有一个关于 软件开发周期的阶段 的帖子，该贴出乎意料地结束了我自己的观察。在Joel看来，第一个阶段是艺术（设计阶段），第二个阶段是工程（构建阶段）第三个阶段是科学（调试和测试阶段）.<br /><br /><div>Joel的兴趣是软件管理和管理工具，但我对于开发工具有更多的兴趣。一旦你认出了软件开发的工程方面和科学方面的分水岭，你就可以更好地理解开发方法的很多紧张对立，其中的一种对立导致了很多辩论。之所以产生这种不安，是因为基本的不变的不可亵渎的（更别说神圣的圣洁的虔诚的）工程法则有时候和科学实践是不一致的。<br /></div><div>也就是说：抽象和模块性是软件工程的心和肺，法则1,2,3是&#8220;局部化关注点，也就是DRY，分离关注点，使关注点正交&#8221;。更简单的说：使用抽象并且不要违反。通过使得一个关注点完全不注意（也就是说：参数化）另一个关注点，你可以最大自由地改变一个关注点而不影响另一个关注点。这是因为(allows for)局部化的原因，依次引发了独立的开发和维护。训练有素的开发者创建分层抽象，并且一丝不苟地遵循他们的边界。<br /><br /><div>但是当开始调试时发生了什么呢？教条地（Dogmatically）遵循抽象边界就像戴了一个眼罩；当一个bug第一次出现的时候，你根本不知道它是隐藏在哪个抽象里，还是在层与层的交互之间。另一个思考抽象盒子内部的通常的推论是 冲动地假设这个bug是别人的错误。（&#8220;一定是编译器的错!&#8221;） 我想起 Knuth 关于计算机科学的引用：</div><div>&nbsp;&nbsp;&nbsp;&nbsp; 这样的人非常擅长处理不同的法则应用到不同情况下的情形，他们是那些可以快速地改变抽象层次，可以同时观察很多大的事物和小的细节的人。&#8212;&#8212;引自 Hartmanis 的图灵奖获奖感言</div><div>我认为这里的描述更多的是在软件开发的科学面或者也可以说是设计方面的&#8212;&#8212;但不是工程方面的。<br /></div><div>因为调试和测试是和观察和理解一个现有的系统相关的，而不是构建或修改一个系统，我们自己构建的藩篱（译注：指层次抽象）使得我们的工程原则变成了障碍。调试工具，集成开发环境，测试框架，等等都被一种需要违反抽象边界的需求而赋予了特色。</div><br /><div>结果，干净和肮脏（就像 Mitch 叫他们的）开始撕咬混战，他们争斗的问题是：我们的软件开发框架 对他们对 FIaI(NtMSHaG)LoE (ML) （译注：实在不知道怎么翻译）的坚持 是应该绝对严格呢，或是绝对宽松(Smalltalk)？ 我不知道通过 构建涵盖这些不同开发模型的软件框架，我们是否能够做的更好。</div><br />=================================================================<br />原文：<br /><br /><div>Joel Spolsky has a post about the <a target="_blank" href="http://www.joelonsoftware.com/items/2007/09/06.html">phases of the software development cycle</a> that's remarkably close to my own observations. In Joel's view, the first phase is <span style="font-weight: bold;">art</span> (i.e., design phase); the second is <span style="font-weight: bold;">engineering</span> (construction); and the third is <span style="font-weight: bold;">science</span> (debugging and testing).<br /><br />Joel's  interest is in project management and management tools, but mine is  more in development tools. Once you recognize the divide between the  engineering and science aspects of software development, you can better  understand one of the tensions in the approach to development, a tension  which leads to plenty of heated debate. This tension comes about  because the Fundamental Immutable and Inviolable (Not to Mention Sacred,  Holy, and Good) Laws of Engineering are sometimes at odds with the  practice of science.<br /><br />To wit: abstraction and modularity are the  heart and lungs of software engineering. Rules #1 , 2 and 3 are  "Localize concerns, i.e. <a target="_blank" href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">Don't Repeat Yourself</a>, separate concerns and enforce their orthogonality." More simply: <span style="font-style: italic;">use abstractions and don't violate them</span>.  By making one concern completely oblivious to (i.e., parametric in)  another, you maximize your freedom to change one without affecting the  other. This allows for local reasoning which in turn leads to separable  development and maintenance. Disciplined developers create layered  abstractions and fastidiously respect their boundaries.<br /><br />But what  happens when you start debugging? Dogmatically adhering to abstraction  boundaries is like wearing blinders; when a bug first arises, you never  know which abstraction layer it's hiding in, or if it's in the  interaction between layers. Another common consequence of thinking  inside the abstraction box is impulsively assuming the bug is someone  else's fault. ("The compiler must be broken!") I'm reminded of Knuth's  quote about computer scientists:<br /><blockquote>Such people are  especially good at dealing with situations where different rules apply  in different cases; they are individuals who can rapidly change levels  of abstraction, simultaneously seeing things "in the large" and "in the  small."<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-- quoted in Hartmanis's <a target="_blank" href="http://portal.acm.org/citation.cfm?id=214781&amp;coll=portal&amp;dl=ACM">Turing Award lecture</a></blockquote>I  think this is describing more the science and perhaps also the design  aspects--but not the engineering aspect--of software development.<br /><br />Because  debugging and testing are about observing and understanding an existing  system, rather than constructing or modifying a system, the barriers we  construct to enforce our engineering principles become obstacles.  Debugging tools, IDE's, testing frameworks, etc. are all characterized  by a need to violate abstraction boundaries.<br /><br />As a result, the  Cleans and Dirties (as Mitch calls them) fight tooth and nail about  whether our software development frameworks should be absolutely strict  in their adherence to the FIaI(NtMSHaG)LoE (ML) or absolutely lax  (Smalltalk). I wonder if we couldn't do better by building software  frameworks that were aware of these different modes of development.</div></div></div></div><img src ="http://www.cppblog.com/qixinkui/aggbug/159272.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/qixinkui/" target="_blank">cingoli</a> 2011-10-28 15:53 <a href="http://www.cppblog.com/qixinkui/archive/2011/10/28/159272.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>