《代码大全》是一本不多见的值得多次阅读的好书,在《代码大全》一书中,每一章后面都有这一章的要点,略读这些要点中我们就可以了解到我们已经掌握了哪些知识,哪些知识还没有掌握,阅读,重读时就有重点了。下面列出这些要点,供没有购买这本书的同学(同仁)参考,或可用作决定“是否应该买这本书”的参考。
第1章 欢迎进入软件构建的世界
中文要点:
软件构建是软件开发的核心活动;构建活动是每个项目中唯一一项必不可少的工作.
软件构建的主要活动包括:详细设计,编码,调试,集成,开发者测试(包括单元测试和集成测试).
构建也常被称作"编码"和"编程".
构建活动的质量对软件的质量有着实质性的影响.
最后,你对"如何进行构建"的理解程度,决定了你这名程序员的优秀程度.
English Key Points:
Software construction the central activity in software development;construction is the only activity that’s guaranteed to happen on every project.
The main activities in construction are detailed design, coding, debugging, and developer testing.
Other common terms for construction are “coding and debugging” and “programming.”
The quality of the construction substantially affects the quality of the software.
In the final analysis, your understanding of how to do construction determines how good a programmer you are, and that’s the subject of the rest of the book.
第2章 用隐喻来更充分的理解软件开发
中文要点:
隐喻是启示而不是算法.因此它们往往有一点随意(sloopy).
隐喻把软件开发过程与其他你熟悉的活动联系在一起,帮助你更好的理解.
有些隐喻比其他一些隐喻更贴切.
通过把软件的构建过程比作是房屋的建设过程,我们可以发现,仔细的准备是必要的,而大型项目和小型项目之间也是有差别的。
通过把软件开发中的实践比作是智慧工具箱中的工具,我们又发现,每位程序员都有许多工具,但并不存在任何一个能适用于所有工作的工具,因地制宜的选择正确工具是成为能有效编程的程序员的关键。
不同的隐喻彼此并不排斥,应当使用对你最有益处的某种隐喻组合。
English Key Points:
Metaphors are heuristics, not algorithms. As such, they tend to be a little sloppy.
Metaphors help you understand the software-development process by relating it to other activities you already know about.
Some metaphors are better than others.
Treating software construction as similar to building construction suggests that careful preparation is needed and illuminates the difference between large and small projects.
Thinking of software-development practices as tools in an intellectual toolbox suggests further that every programmer has many tools and that no single tool is right for every job. Choosing the right tool for each problem is one key to being an effective programmer.
?
第3章 三思而后行:前期准备
中文要点:
构建活动的准备工作的根本目标在于降低风险。要确认你的准备活动是在降低风险,而非增加风险。
如果你想开发高质量的软件,软件开发过程必须由始至终关注质量。在项目初期关注质量,对产品质量的正面影响比在项目末期关注质量的影响要大。
程序员的一部分工作是教育老板和合作者,告诉他们软件开发过程,包括在开始编程之前进行充分准备的重要性。
你所从事的软件项目的类型对构建活动的前期准备有重大影响——许多项目应该是高度迭代式的,某些应该是序列式的。
如果没有明确的问题定义,那么你可能会在构建期间解决错误的问题。
如果没有做完良好的需求分析工作,你可能没能察觉待解决的问题的重要细节。如果需求变更发生在构建之后的阶段,其代价是“在项目早期更改需求”的 20至 100 倍。因此在开始编程之前,你要确认“需求”已经到位了。
如果没有做完良好的架构设计,你可能会在构建期间用错误的方法解决正确的问题。架构变更的代价随着“为错误的架构编写的代码数量”增加而增加,因此,也要确认“架构”已经到位了。
理解项目的前期准备所采用的方法,并相应地选择构建方法。
English Key Points:
The overarching goal of preparing for construction is risk reduction. Be sure your preparation activities are reducing risks, not increasing them.
If you want to develop high-quality software, attention to quality must be part of the software-development process from the beginning to the end. At tention to quality at the beginning has a greater influence on product quality than attention at the end.
Part of a programmer’s job is to educate bosses and coworkers about the software-development process, including the importance of adequate preparation before programming begins.
The kind of project you’re working significantly affects construction prerequisites—many projects should be highly iterative, and some should be more sequential.
If a good problem definition hasn’t been specified, you might be solving the wrong problem during construction.
If a good requirements work hasn’t been done, you might have missed important details of the problem. Requirements changes cost 20 to 100 times as much in the stages following construction as they do earlier, so be sure the requirements are right before you start programming.
If a good architectural design hasn’t been done, you might be solving the right problem the wrong way during construction. The cost of architectural changes increases as more code is written for the wrong architecture, so be sure the architecture is right too.
Understand what approach has been taken to the construction prerequisites on your project and choose your construction approach accordingly.
第4章 关键的“构建”决策
中文要点:
每种编程语言都有其优点和弱点。要知道你使用的语言的明确优点和弱点。
在开始编程之前,做好一些约定(convention)。“改变代码使之符合这些约定”是近乎不可能的。
“构建的实践方法”的种类比任何单个项目能用到的要多。有意识地选择最适合你的项目的实践方法。
问问你自己,你采用的编程实践是对你所用的编程语言的正确响应,还是受它的控制?请记得“深入一种语言去编程”,不要仅“在一种语言上编程”。
你在技术浪潮中的位置决定了哪种方法是有效的——甚至是可能用到的。确定你在技术浪潮中的位置,并相应调整计划和预期目标。
English Key Points:
Every programming language has strengths and weaknesses. Be aware of the specific strengths and weaknesses of the language you’re using.
Establish programming conventions before you begin programming. It’s nearly impossible to change code to match them later.
More construction practices exist than you can use on any single project.Consciously choose the practices that are best suited to your project.
?
Your position on the technology wave determines what approaches will be effective—or even possible. Identify where you are on the technology wave, and adjust your plans and expectations accordingly.
第5章 软件构建中的设计
中文要点:
软件的首要技术使命就是管理复杂度。以简单性作为努力目标的设计方案对此最有帮助。
简单性可以通过两种方式来获取:一是减少在同一时间所关注的本质性复杂度的量,二是避免生成不必要的偶然的复杂度。
设计是一种启发式的过程。固执于某一种单一方法会损害创新能力,从而损害你的程序。
好的设计都是迭代的。你尝试设计的可能性越多,你的最终设计方案就会变得越好。
信息隐藏是个非常有价值的概念。通过询问“我应该隐藏些什么?”能够解决很多困难的设计问题。
很多有用有趣的、关于设计的信息存在于本书之外。这里所给出的观点只是对这些有价值资源的一点提示而已。
English Key Points:
Software’s Primary Technical Imperative is managing complexity. This is accomplished primarily through a design focus on simplicity.
Simplicity is achieved in two general ways: minimizing the amount of essential complexity that anyone’s brain has to deal with at any one time and keeping accidental complexity from proliferating needlessly.
Design is heuristic. Dogmatic adherence to any single methodology hurts creativity and hurts your programs.
Good design is iterative; the more design possibilities you try, the better your final design will be.
Information hiding is a particularly valuable concept. Asking, “What should I hide?” settles many difficult design issues.
Lots of useful, interesting information on design is available outside this book. The perspectives presented here are just the tip of the iceberg.
第6章 可以工作的类
中文要点:
类的接口应提供一致的抽象。很多问题都是由于违背该原则而引起的。
类的接口应隐藏一些信息――如某个系统接口、某项设计决策、或一些实现细节。
包含往往比继承更为可取――除非你要对“是一个/is a”的有关系建模。
继承是一种有用的工具,但它却会增加复杂度,这有违于软件的首要技术使命――管理复杂度。
类是管理复杂度的首选工具。要在设计类时给予足够的关注,才能实现这一目标。
English Key Points:
Class interfaces should provide a consistent abstraction. Many problems arise from violating this single principle.
A class interface should hide something—a system interface, a design decision, or an implementation detail.
Containment is usually preferable to inheritance unless you’re modeling an “is a” relationship.
Inheritance is a useful tool, but it adds complexity, which is counter to the Primary Technical Imperative of minimizing complexity.
Classes are your primary tool for managing complexity. Give their design as much attention as needed to accomplish that objective.
第7章 高质量的子程序
中文要点:
创建子程序最主要的目的是提高程序的可管理性,当然也有其他一些好的理由。其中,节省代码空间只是一个次要原因:提高可读性、可靠性和可修改性等原因都更重要一些。
有时候,把一些简单的操作写成独立的子程序也非常有价值。
子程序可以按照其内聚性分为很多类,而你应该让大多数程序具有功能上的内聚性,这是最佳的一种内聚性。
子程序的名字是它的质量的指示器。如果名字糟糕但恰如其分,那就说明这个子程序设计得很差劲。如果名字糟糕而且又不准确,那么它就反映不出程序是干什么的。不管怎样,糟糕的名字都意味着程序需要修改。
只有在某个子程序的主要目的是返回由其名字所描述的特定结果时,才应该使用函数。
细心的程序员会非常谨慎地使用宏,而且只在万不得已时才用。
English Key Points:
The most important reason to create a routine is to improve the intellectual manageability of a program, and you can create a routine for many other good reasons. Saving space is a minor reason; improved readability, reliability, and modifiability are better reasons.
Sometimes the operation that most benefits from being put into a routine of its own is a simple one.
The name of a routine is an indication of its quality. If the name is bad and it’s accurate, the routine might be poorly designed. If the name is bad and it’s inaccurate, it’s not telling you what the program does. Either way, a bad name means that the program needs to be changed.
Functions should be used only when the primary purpose of the function is to return the specific value described by the function’s name.
Careful programmers use macro routines and inline routines with care, and only as a last resort.
第8章 防御式编程
中文要点:
最终产品代码中对错误的处理方式要比“垃圾进,垃圾出”复杂的多。
防御式编程技术可以让错误更容易发现、更容易修改,并减少错误对产品代码的破坏。
断言可以帮助人尽早发现错误,尤其是在大型系统和高可靠性的系统中,以及快速变化的代码中。
关于如何处理错误输入的决策是一项关键的错误处理决策,也是一项关键的高层设计决策。
异常提供了一种与代码正常流程角度不同的错误处理手段。如果留心使用异常,它可以成为程序员们知识工具箱中的一项有益补充,同时也应该在异常和其他错误处理手段之间进行权衡比较。
针对产品代码的限制并不适用于开发中的软件。你可以利用这一优势在开发中添加有助于更快地排查错误的代码。
English Key Points:
Production code should handle errors in a more sophisticated way than “garbage in, garbage out.”
Defensive-programming techniques make errors easier to find, easier to fix, and less damaging to production code.
Assertions can help detect errors early, especially in large systems, high reliability systems, and fast-changing code bases.
The decision about how to handle bad inputs is a key error-handling decision, and a key high-level design decision.
Exceptions provide a means of handling errors that operates in a different dimension from the normal flow of the code. They are a valuable addition to the programmer’s toolkit when used with care, and should be weighed against other error-processing techniques.
Constraints that apply to the production system do not necessarily apply to the development version. You can use that to your advantage, adding code to the development version that helps to flush out errors quickly.
第9章 伪代码编程过程
中文要点:
创建类和子程序通常都是一个迭代的过程。在创建子程序的过程中获得的认识常常会反过来影响类的设计。
编写好的伪代码需要使用易懂的英语,要避免使用特定程序语言中才有的特性,同时要在意图的层面上写伪代码(即描述该做什么,而不是要怎么去做)。
伪代码编程过程是一个行之有效的做详细设计的工具,它同时让编码工作更容易。伪代码会直接转化为注释,从而确保了注释的准确度和实用性。
不要只停留在你所想到的第一个设计方案上。反复使用伪代码做出多种方案,然后选出其中最佳的一种方案再开始编码。
每一步完成后都要检查你的工作成果,还要鼓励其他人帮你来检查。这样你就会在投入精力最少的时候,用最低的成本发现错误。
English Key Points:
Constructing classes and constructing routines tends to be an iterative process. Insights gained while constructing specific routines tend to ripple back through the class’s design.
Writing good pseudocode calls for using understandable English, avoiding features specific to a single programming language, and writing at the level of intent—describing what the design does rather than how it will do it.
The Pseudocode Programming Process is a useful tool for detailed design and makes coding easy. Pseudocode translates directly into comments,ensuring that the comments are accurate and useful.
Don’t settle for the first design you think of. Iterate through multiple approaches in pseudocode and pick the best approach before you begin writing code.
Check your work at each step and encourage others to check it too. That way, you’ll catch mistakes at the least expensive level, when you’ve invested the least amount of effort.
第10章 使用变量的一般事项
中文要点:
数据初始化过程很容易出错,所以请用本章描述的初始化方法来避免由于非预期的初始值而造成的错误。
最小化每个变量的作用域。把同一变量的引用点集中在一起。把变量限定在或类的范围之内。避免使用全局数据。
把使用相同变量的语句尽可能集中在一起。
早期在绑定会减低灵活性,但有助于减小复杂度。晚期绑定可以增加灵活性,同时增加复杂度。
把每个变量用于唯一的用途。
English Key Points:
Data initialization is prone to errors, so use the initialization techniques described in this chapter to avoid the problems caused by unexpected initial values.
Minimize the scope of each variable. Keep references to it close together. Keep it local to a routine or class. Avoid global data.
Keep statements that work with the same variables as close together as possible.
Early binding tends to limit flexibility, but minimize complexity. Late binding tends to increase flexibility, but at the price of increased complexity.
Use each variable for one and only one purpose.
第11章 变量名的力量
中文要点:
好的变量名是提高程序可读性的一项关键要素。对特殊种类的变量,比如循环下标和状态变量,需要加以特殊的考虑。
名字要尽可能地具体。那些太模糊或者太能用以致于能够用于多种目的的名字通常都是很不好的。
命名规则应该能够区分局部数据、类数据和全局数据。它们还应当可以区分类型名、具名常量、枚举类型名字和变量名。
无论做哪种类型项目,你都应该采用某种变量命名规则。你所采用的规则的种类取决于你的程序的规模,以及项目成员的人数。
现代编程语言很少需要用到缩写。如果你真的要使用缩写,请使用项目缩写词典或者标准前缀来帮助理解缩写。
代码阅读的次数远远多于编写的次数。确保你所取的名字更侧重于阅读方便而不是编写方便。
English Key Points:
Good variable names are a key element of program readability. Specific kinds of variables such as loop indexes and status variables require specific considerations.
Names should be as specific as possible. Names that are vague enough or general enough to be used for more than one purpose are usually bad names.
Naming conventions distinguish among local, class, and global data. They distinguish among type names, named constants, enumerated types, and variables.
Regardless of the kind of project you’re working on, you should adopt a variable naming convention. The kind of convention you adopt depends on the size of your program and the number of people working on it.
Abbreviations are rarely needed with modern programming languages. If you do use abbreviations, keep track of abbreviations in a project dictionary or use the Standardized Prefixes approach.
第12章 基本数据类型
中文要点:
使用特定的数据类型就意味着要记住适用于各个类型的很多独立的原则。用本章的核对表来确认你已经对觉问题做了考虑。
如果你的语言支持,创建自定义类型会使得你的程序更容易修改,并更具有自描述性。
当你用typedef或者其等价方式创建了一个简单类型的时候,考虑是否更应该创建一个新的类。
English Key Points:
Working with specific data types means remembering many individual rules for each type. Use the checklist to make sure that you’ve considered the common problems.
Creating your own types makes your programs easier to modify and more self-documenting, if your language supports that capability.
When you create a simple type using typedef or its equivalent, consider whether you should be creating a new class instead.
第13章 不常见的数据类型
中文要点:
结构体可以使得程序更简单、更容易理解,以及更容易维护。
每当你打算使用结构体的时候,考虑采用类是不是会工作的更好。
指针很容易出错。用访问器子程序或类以及防御式编程实践来保护自己的代码。
避免用全局变量,不只是因为它们很危险,还是因为你可以用其他更好的方法来取代它们。
如果你不得不使用全局变量,那么就通过访问器来使用它。访问器子程序能为你带来全局变量所能带来的一切优点,还有一些额外的好处。
English Key Points:
Structures can help make programs less complicated, easier to understand,and easier to maintain.
Whenever you consider using a structure, consider whether a class would work better.
Pointers are error prone. Protect yourself by using access routines or classes and defensive-programming practices.
Avoid global variables, not just because they’re dangerous, but because you can replace them with something better.
If you can’t avoid global variables, work with them through access routines.Access routines give you everything that global variables give you, and more.
第14章 组织直线型代码
中文要点:
组织直线型代码的最主要原则是按照依赖关系进行排列。
可以用好的子程序名、参数列表、注释,以及――如果代码足够重要――内务管理变量来让依赖关系变得更明显。
如果代码之间没有顺序依赖关系,那就设法使相关的语句尽可以地接近。
English Key Points:
The strongest principle for organizing straight-line code is order dependencies.
Dependencies should be made obvious through the use of good routine names, parameter lists, comments, and—if the code is critical enough—housekeeping variables.
If code doesn’t have order dependencies, keep related statements as close together as possible.
第15章 使用条件语句
中文要点:
对于简单的if-else语句,请注意if子句和else子句的顺序,特别是用它来处理大量错误的时候。要确认正常的情况是清晰的。
对于if-then-else语句串和case语句,选择一种最有利于阅读的排序。
为了捕捉错误,可以使用case语句中的default子句(默认子句),或者使用if-then-else语句串中的最后那个else子句。
各种控制结构并不是生来平等的。请为代码的每个部分选用最合适的控制结构。
English Key Points:
For simple if-elses, pay attention to the order of the if and else clauses,especially if they process a lot of errors. Make sure the nominal case is clear.
For if-then-else chains and case statements, choose an order that maximizes readability.
Use the default clause in a case statement or the last else in a chain of if then-elses to trap errors.
All control constructs are not created equal. Choose the control construct that’s most appropriate for each section of code.
第16章 控制循环
中文要点:
循环很复杂。保持循环简单将有助于别人阅读你的代码。
操持循环简单的技巧包括:避免使用怪异的循环、减少嵌套层次、让入口和出口一目了然、把内务操作代码放在一起。
循环下标很容易被滥用。因此命名要准确,并且要把它们各自仅用于一个用途。
仔细地考虑循环,确认它在每一种情况下都运行正常,并且在所有可能的条件下都能退出。
English Key Points:
Loops are complicated. Keeping them simple helps readers of your code.
Techniques for keeping loops simple include avoiding exotic kinds of loops, minimizing nesting, making entries and exits clear, and keeping housekeeping code in one place.
Loop indexes are subjected to a great deal of abuse. Name them clearly and use them for only one purpose.
Think the loop through carefully to verify that it operates normally under each case and terminates under all possible conditions.
第17章 不常见的控制结构
中文要点:
多个return可以增强子程序的可读性和可维护性,同时可以避免产生很深的嵌套逻辑。但是使用它的时候要多加小心。
递归能够很优雅地解决一小部分问题。对它的使用也要倍加小心 。
在少数情况下,goto是编写可读性和可维护性代码的最佳方法。但这种情况非常罕见。除非万不得忆,不要使用goto.
English Key Points:
Multiple returns can enhance a routine’s readability and maintainability, and they help prevent deeply nested logic. They should, nevertheless, be used carefully.
Recursion provides elegant solutions to a small set of problems. Use it carefully, too.
In a few cases, gotos are the best way to write code that’s readable and maintainable. Such cases are rare. Use gotos only as a last resort.
第18章 表驱动法
中文要点:
表提供了一种复杂的逻辑和继承结构的替换方案。如果你发现自己对某个应用程序的逻辑或者继承树关系感到困惑,那么问问自己它是否可以通过一个查询表来加以简化。
使用表的一项关键决策是决定如何去访问表。你可以采取直接访问、索引访问或者阶梯访问。
使用表的另一项关键决策是决定应该把什么内容放入表中。
English Key Points:
Tables provide an alternative to complicated logic and inheritance structures.If you find that you’re confused by a program’s logic or inheritance tree, ask yourself whether you could simplify by using a lookup table.
One key consideration in using a table is deciding how to access the table.You can access tables using direct access, indexed access, or stair-step access.
Another key consideration in using a table is deciding what exactly to put into the table.
第19章 一般控制问题
中文要点:
使用布尔表达式简单可读,将非常有助于提高 你的代码质量。
深层次的嵌套使得子程序变得难以理解。所幸的是,你可以相对容易地避免这么做。
结构化编程是一种简单并且仍然适用的思想:你可以通过把顺序、选择和循环三者组合起来而开发出任何程序。
将复杂降低到最低水平是编写高质量代码的关键。
English Key Points:
Making boolean expressions simple and readable contributes substantially to the quality of your code.
Deep nesting makes a routine hard to understand. Fortunately, you can avoid it relatively easily.
Structured programming is a simple idea that is still relevant: you can build any program out of a combination of sequences, selections, and iterations.
Minimizing complexity is a key to writing high-quality code.
第20章 软件质量概述
中文要点:
开发高质量代码最终并没有要求你付出更多,只是你需要对资源进行重新分配,以低廉的成本来防止缺陷出现,从而避免代价高昂的修正工作。
并非所有的质量保证目标都可以全部实现。明确哪些目标是你希望达到的,并就这些目标和团队成员进行沟通。
没有任何一种错误检测方法能够解决全部问题,测试本身并不是排队错误的最有效方法。成功的质量保证计划应该使用多种不同的技术来检查各种不同类型的错误。
在构建期间应当使用一些有效的质量保证技术,但在这之前,一些具有同样强大功能的质量保证技术也是必不可少的。错误发现越早,它与其余代码的纠缠就越少,由此造成的损失也越少。
软件领域的质量保证是面向过程的。软件开发与制造业不一样,在这里并不存在会影响最终产品的重复的阶断,因此,最终产品的质量受到开发软件所用的过程的控制。
English Key Points:
Quality is free, in the end, but it requires a reallocation of resources so that defects are prevented cheaply instead of fixed expensively.
Not all quality-assurance goals are simultaneously achievable. Explicitly decide which goals you want to achieve, and communicate the goals to other people on your team.
No single defect-detection technique is effective by itself. Testing by itself is not effective at removing errors. Successful quality-assurance programs use several different techniques to detect different kinds of errors.
You can apply effective techniques during construction and many equally powerful techniques before construction. The earlier you find a defect, the less damage it will cause.
Quality assurance in the software arena is process-oriented. Software development doesn’t have a repetitive phase that affects the final product like manufacturing does, so the quality of the result is controlled by the process used to develop the software.
第21章 协同构建
中文要点:
协同开发实践往往能比测试发现更多的缺陷,并且更有效率。
协同开发实践所发现错误的类型通常跟测试所发现的不同,这意味着你需要同时使用和测试来保证你软件的质量。
正式检查通过运用核对表、准备工作、明确定义的角色以及对方法的持续改善,将缺陷侦测的效率提升至最高。它往往能比走查发现更多的缺陷。
通常,结对编程拥有和详查相同的成本,并能产生质量相当的代码。当需要缩短开发周期的时候,结对编程就非常有价值。相对于单独工作来说,有些开发人员更喜欢结对工作。
正式检查可以应用在除代码之外的很多工作成果上,例如需求、设计以及测试用例等。
走查的代码阅是详查的替代方案。代码阅读更富有弹性,能有效地利用每个人的时间。
English Key Points:
Collaborative development practices tend to find a higher percentage of defects than testing and to find them more efficiently.
Collaborative development practices tend to find different kinds 674 nds of errors than testing does, implying that you need to use both reviews and testing to ensure the quality of your software.
Formal inspections use checklists, preparation, well-defined roles, and continual process improvement to maximize error-detection efficiency. They tend to find more defects than walkthroughs.
Pair programming typically costs about the same as inspections and produces similar quality code. Pair programming is especially valuable when schedule reduction is desired. Some developers prefer working in pairs to working solo.
Formal inspections can be used on workproducts such as requirements, designs, and test cases as well as on code.
Walkthroughs and code reading are alternatives to inspections. Code reading offers more flexibility in using each person’s time effectively.
第22章 开发者测试
中文要点:
开发人员测试是完整测试策略的一个关键部分。独立测试也很重要,但这一主题超出了本书的范围。
同编码之后编写测试用例相比较,编码开始之前编写测试用例,工作量和花费的时间差不多,但是后者可以缩短缺陷-侦测-调试-修正这一周期。
即使考虑到了各种可用的测试手段,测试仍然只是良好软件质量计划的一部分。高质量的开发方法至少和测试一样重要,这包括尽可能减少需求和设计阶段的缺陷。在检测错误方面,协同开发的成效至少与测试相当。这些方法所检测错误的类型也不相同。
你可以根据各种不同的思路来产生很多测试用例,这些思路包括基础测试、数据流分析、边界分析、错误数据类型以及正确数据类型等。你可以通过猜测错误的方式得到更多的测试用例。
错误往往集中在少数几个容易出错的类和子程序上。找出这部分代码,重新设计和编写它们。
测试数据本身出错的密度往往比被测代码还要高。查找这种错误完全是浪费时间,又不能对代码有所改善,因此测试数据里面的错误更加让人烦恼。要像代码一样小心地开发测试用例,这样才能避免产生这种问题。
自动化测试总体来说是很有用的,也是进行回归测试的基础。
从长远来看,改善测试过程的最好办法就是将其规范化,并对其进行评估,然后从评估中获得的经验教训来改善这个过程。
English Key Points:
Testing by the developer is a key part of a full testing strategy. Independent testing is also important but is outside the scope of this book.
Writing test cases before the code takes the same amount of time and effort as writing the test cases after the code, but it shortens defect-detection debug-correction cycles.
Even considering the numerous kinds of testing available, testing is only one part of a good software-quality program. High-quality development methods, including minimizing defects in requirements and design, are at least as important. Collaborative development practices are also at least as effective at detecting errors as testing and detect different kinds of errors.
You can generate many test cases deterministically using basis testing, data flow analysis, boundary analysis, classes of bad data, and classes of good data. You can generate additional test cases with error guessing.
Errors tend to cluster in a few error-prone classes and routines. Find that error-prone code, redesign it, and rewrite it.
Test data tends to have a higher error density than the code being tested. Because hunting for such errors wastes time without improving the code, test-data errors are more aggravating than programming errors. Avoid them by developing your tests as carefully as your code.
Automated testing is useful in general and essential for regression testing.
In the long run, the best way to improve your testing process is to make it regular, measure it, and use what you learn to improve it.
第23章 调试
中文要点:
调试同整个软件开发的成败息息相关。最好的解决之道是使用本书中介绍的其他方法来避免缺陷的产生。然而,花点时间来提高自己的调试技能还是很划算的,因为优秀和拙劣的调试表现之间的差距至少是10:1。
要想成功,系统化地查找和改正错误的方法至关重要。要声浪于你的调试工作,让每一次测试都能让你朝着正确的方向前进一步。要使用科学的调试方法。
在动手解决问题之前,要理解问题的根本。胡乱猜测错误的来源和随机修改将会让你的程序陷入比刚开始调试时更为糟糕的境地。
将编译器警告级别设置为最严格,把警告信息所报告的错误都改正。如果你忽略了明显的错误,那么要改正那些微妙的错误就会非常麻烦。
调试工具对软件开发而言是强有力的支持手段。找出这些工具并加以应用,当然,请记得在调试的时候开动脑筋。
English Key Points:
Debugging is a make-or-break aspect of software development. The best approach is to use other techniques described in this book to avoid defects in the first place. It’s still worth your time to improve your debugging skills, however, because the difference between good and poor debugging performance is at least 10 to 1.
A systematic approach to finding and fixing errors is critical to success. Focus your debugging so that each test moves you a step forward. Use the Scientific Method of Debugging.
Understand the root problem before you fix the program. Random guesses about the sources of errors and random corrections will leave the program in worse condition than when you started.
Set your compiler warning to the pickiest level possible, and fix the errors it reports. It’s hard to fix subtle errors if you ignore the obvious ones.
Debugging tools are powerful aids to software development. Find them and use them. Remember to use your brain at the same time.
第24章 重构
中文要点:
修改程序是程序一生都要面对的事情,不仅包括最初的开发阶段,还包括首次发布之后。
在修改中软件的质量要么改进,要么恶化。软件演化的首要法则就是代码演化应当提升程序的内存质量。
重构成功之关键在于程序员应学会关注那些标志着代码需要重构的众多的警告或“代码臭味”。
重要成功的另一要素是程序员应当掌握大量特定的重构方法。
重构成功的最后要点在于要有安全重构的策略。一些重构方法会比其他重构的方法要好。
开发阶段的重构是提升程序质量的最佳时机,因为你可以立刻让刚刚产生的改变梦想变成现实。请珍惜这些开发阶段的天赐良机!
English Key Points:
Program changes are a fact of life both during initial development and after initial release.
Software can either improve or degrade as it’s changed. The Cardinal Rule of Software Evolution is that internal quality should improve with age.
One key to success in refactoring is learning to pay attention to the numerous warning signs or smells that indicate a need to refactor.
Another key to success is learning numerous specific refactorings.
A final key to success is having a strategy for refactoring safely. Some approaches to refactoring are better than others.
Refactoring during development is the best chance you’ll get to improve your program, to make all the changes you’ll wish you’d made the first time.Take advantage of it!
第25章 代码调整策略
中文要点:
性能只是软件整体质量的一个方面,通常不是最重要的。精细的代码调整也只是实现整体性能的一种方法,通常也不是决定性的。相对于代码本身的效率而言,程序的架构、细节设计以及数据结构和算法选择对程序的运行速度和资源占用的影响通常会更大。
定量测量是实现性能最优化的关键。定量测量需要找出能真正决定程序性能的部分,在修改之后,应当通过重复测量来明确修改是提高还是降低了软件的性能。
绝大多数的程序都有那么一小部分代码耗费了绝大部分的运行时间。如果没有测量,你不会知道是哪一部分代码。
代码调整需要反复尝试,这样才能获得理想的性能提高。
为性能优化工作做好准备的最佳方式就是在最初阶段编写清晰的代码,从而使代码在后续工作中易于理解和修改。
English Key Points:
Performance is only one aspect of overall software quality, and it’s usually not the most important. Finely tuned code is only one aspect of overall performance, and it’s usually not the most significant. Program architecture, detailed design, and data-structure and algorithm selection usually have more influence on a program’s execution speed and size than the efficiency of its code does.
Quantitative measurement is a key to maximizing performance. It’s needed to find the areas in which performance improvements will really count, and it’s needed again to verify that optimizations improve rather than degrade the software.
Most programs spend most of their time in a small fraction of their code. You won’t know which code that is until you measure it.
Multiple iterations are usually needed to achieve desired performance improvements through code tuning.
The best way to prepare for performance work during initial coding is to write clean code that’s easy to understand and modify.
第26章 代码调整技术
中文要点:
优化结果在不同的语言、编译器和环境下有很大差异。如果没有对每一次的优化进行测量,你将无法判断优化到底是帮助还是损害了这个程序 。
第一次优化通常不会是最好的。即使找到了效果很不错的,也不要停下扩大战果的步伐。
代码调整这一话题有点类似于核能,富于争议,甚至会让人冲动。一些人认为代码调整损害了代码可读性和可维护性,他们绝对会将其弃之不用。其他人则认为只要有适当的安全保障,代码调整对程序是有益的。如果你决定使用本章所述的调整方法,请务必谨慎行事。
English Key Points:
Results of optimizations vary widely with different languages, compilers, and environments. Without measuring each specific optimization, you’ll have no idea whether it will help or hurt your program.
The first optimization is often not the best. Even after you find a good one, keep looking for one that’s better.
Code tuning is a little like nuclear energy. It’s a controversial, emotional topic. Some people think it’s so detrimental to reliability and maintainability that they won’t do it at all. Others think that with proper safeguards, it’s beneficial. If you decide to use the techniques in this chapter, apply them with care.
第27章 程序规模对构建的影响
中文要点:
随着项目规模的扩大,交流需要加以支持。大多数方法论的关键点都在于减少交流中的问题,而一项方法论的存亡关键也应取决于它能否促进交流。
在其他条件都相等的时候,大项目的生产率会低于小项目。
在其他条件都相等的时候,大项目的每千行代码错误率会高于小项目。
在小项目里的一些看起来“理当如此”的活动在大项目中必须仔细地计划。随着项目规模扩大,构建活动的主导地位逐渐降低。
放大轻量级的方法论要好于缩小重量级的方法论。最有效的办法是使用“适量级”方法论。
English Key Points:
As project size increases, communication needs to be supported. The point of most methodologies is to reduce communications problems, and a methodology should live or die on its merits as a communication facilitator.
All other things being equal, productivity will be lower on a large project than on a small one.
All other things being equal, a large project will have more errors per line of code than a small one.
Activities that are taken for granted on small projects must be carefully planned on larger ones. Construction becomes less predominant as project size increases.
Scaling-up a light-weight methodology tends to work better than scaling down a heavy-weight methodology. The most effective approach of all is using a “right-weight” methodology.
第28章 管理构建
中文要点:
好的编码实践可以通过“贯彻标准”或者“使用更为灵活的方法”来达到。
配置管理,如果应用得当,会使程序序员的工作变得更加轻松。特别包括为变更控制。
好的软件评估是一项重大挑战。成功的关键包括采用多种方法、随着项目的开展而修缮评估结果,以及很好地利用数据来创建评估等。
度量是构建管理成功的关键。你可以采取措施度量项目的任何方面,而这要比根本不度量好的多。准确的度量是制定准确的进度表、质量控制和改进开发过程的关键。
程序员和管理人员都是人,在把他们当人看的时候工作得最好。
English Key Points:
Good coding practices can be achieved either through enforced standards or through more light-handed approaches.
Configuration management, when properly applied, makes programmers’jobs easier. This especially includes change control.
Good software estimation is a significant challenge. Keys to success are using multiple approaches, tightening down your estimates as you work your way into the project, and making use of data to create the estimates.
Measurement is a key to successful construction management. You can find ways to measure any aspect of a project that are better than not measuring it at all. Accurate measurement is a key to accurate scheduling, to quality control, and to improving your development process.
Programmers and managers are people, and they work best when treated as such.
第29章 集成
中文要点:
构建的先后次序和集成的步骤会影响设计、编码、测试各类的顺序。
一个经过充分思考的集成顺序能减少测试的工作量,并使用调试变容易。
增量集成有若干变型,而且――除非项目是微不足道的――任何一种形式的增量集成都比阶段式集成好。
针对每个特定的项目,最佳的集成步骤通常是自顶向下、自底向上、风险导向及其他集成方法的某种组合。T-型集成和竖直分块集成通常都能工作得很好。
Daily build能减少集成的问题,提升开发人员的士气,并提供非常有用的项目管理信息。
English Key Points:
The construction sequence and integration approach affect the order in which classes are designed, coded, and tested.
A well-thought-out integration order reduces testing effort and eases debugging.
Daily builds can reduce integration problems, improve developer morale, and provide useful project management information.
Incremental integration comes in several varieties, and, unless the project is trivial, any one of them is better than phased integration.
The best integration approach for any specific project is usually a combination of top-down, bottom-up, risk-oriented, and other integration approaches. T-shaped integration and vertical-slice integration are two approaches that often work well.
第30章 编程工具
中文要点:
程序员有时会长达数年的时间里忽视某些最强大的工具,之后才发现并使用之。
好的工具能让你的日子过的安逸得多。
下面这些工具已经可用了:编辑、分析代码质量、重构、版本控制、除错、测试、代码调整。
你能打造许多自己用的专用工具。
好的工具能减少软件开发中最单调乏味的工作的量,但它不能消除对“编程”的需要,虽然它会持续地重塑(reshape)编程的含义。
English Key Points:
Programmers sometimes overlook some of the most powerful tools for years before discovering them.
Good tools can make your life a lot easier.
Tools are readily available for editing, analyzing code quality, refactoring, version control, debugging, testing, and code tuning.
You can make many of the special-purpose tools you need.
Good tools can reduce the more tedious aspects of software development, but they can’t eliminate the need for programming, though they will continue to reshape what we mean by “programming.”
第31章 布局与风格
中文要点:
可视化布局的首要任务是指明代码的逻辑组织。评估该任务是否实现的指标包括准确性、一致性、易读性和易维护性。
外表悦目比起其他指标是最不重要的。然而,如果其他指标都达到了,代码又质量好,那么布局效果看上去也会不错。
Visual Basic具有纯代码块风格,而Java的传统做法就是使用纯块风格,所以若用这些语言编程,就请使用纯代码块风格。C++中,模拟纯代码块或者begin-end块边界都行之有效。
结构化代码有其自身目的。始终如一地沿用某个习惯而少来创新。不能持久的布局规范只会损害可读性。
布局的很多方面涉及信仰问题。应试着将客观需要和主观偏好区分开来。定出明确的指标,在此基础上再讨论风格参数的选择。
English Key Points:
The first priority of visual layout is to illuminate the logical organization of the code. Criteria used to assess whether the priority is achieved include accuracy, consistency, readability, and maintainability.
Looking good is secondary to the other criteria—a distant second. If the other criteria are met and the underlying code is good, however, the layout will look fine.
Visual Basic has pure blocks and the conventional practice in Java is to use pure block style, so you can use a pure-block layout if you program in those languages. In C++, either pure-block emulation or begin-end block boundaries work well.
Structuring code is important for its own sake. The specific convention you follow may be less important than the fact that you follow some convention consistently. A layout convention that’s followed inconsistently might actually hurt readability.
Many aspects of layout are religious issues. Try to separate objective preferences from subjective ones. Use explicit criteria to help ground your discussions about style preferences.
第32章 自说明代码
中文要点:
该不该注释是一个需要认真对待的问题。差劲的注释只会浪费时间,帮倒忙:好的注释才有价值。
源代码应当含有程序大部分的关键信息。只要程序谷底大用,源代码比其他资料都能保持更新,故而将重要信息融入代码是很有用处的。
好代码本身就是更好的说明。如果代码太糟,需要大量注释,应先试着改进代码,直至无须过多注释为止。
注释应说出代码无法说出的东西――例如概述或用意等信息。
有的注释风格需要许多重复性劳动,应舍弃之,改用易于维护的注释风格。
English Key Points:
The question of whether to comment is a legitimate one. Done poorly, commenting is a waste of time and sometimes harmful. Done well, commenting is worthwhile.
The source code should contain most of the critical information about the program. As long as the program is running, the source code is more likely than any other resource to be kept current, and it’s useful to have important information bundled with the code.
Good code is its own best documentation. If the code is bad enough to require extensive comments, try first to improve the code so that it doesn’t need extensive comments.
Comments should say things about the code that the code can’t say about itself—at the summary level or the intent level.
Some commenting styles require a lot of tedious clerical work. Develop a style that’s easy to maintain.
第33章 个人性格
中文要点:
人的个性对其编程能力有直接影响 。
最有关系的性格为:谦虚、求知欲、诚实、创造性和纪律,以及高明的偷懒。
程序员高手的性格与天分无关,而任何事都与个人发展相关。
出乎意料的是,小聪明、经验、坚持和疯狂既有助也有害。
很多程序员不愿意主要吸收新知识和技术,只依靠工作时偶尔接触新的信息。如果你能抽出少量时间阅读和学习编程知识,要不了多久就能鹤立鸡群。
好性格与培养正确的习惯关系甚大。要成为杰出的程序员,先要养成良好习惯,其他自然水到渠成。
English Key Points:
Your personal character directly affects your ability to write computer programs.
The characteristics that matter most are humility, curiosity, intellectual honesty, creativity and discipline, and enlightened laziness.
The characteristics of a superior programmer have almost nothing to do with talent and everything to do with a commitment to personal development.
Surprisingly, raw intelligence, experience, persistence, and guts hurt as much as they help.
Many programmers don’t actively seek new information and techniques and instead rely on accidental, on-the-job exposure to new information. If you devote a small percentage of your time to reading and learning about programming, after a few months or years you’ll dramatically distinguish yourself from the programming mainstream.
Good character is mainly a matter of having the right habits. To be a great programmer, develop the right habits, and the rest will come naturally.
第34章 软件工艺的话题
中文要点:
编程的主要主的之一是管理复杂性。
编程过程对最终产品有深远影响 。
合作开发要求团队成员之间进行广泛沟通,甚于同计算机的交互;而单人开发则是自我交流,其次才是计算机。
编程规范一旦滥用,只会雪上加霜;使用得当则能为开发环境带来良好机制,有助于管理复杂性和相互沟通。
编程应基于问题域而非解决方案,这样便于复杂性管理。
注意警告信息,将其作为编程的疑点,因为编程几乎是纯粹的智力活动。
开发时迭代次数越多,产品的质量越好。
墨守成规的方法有悖于高质量的软件开发。请将编程工具箱中填满各种编程工具,不断提高自己换行合适工具的能力。
English Key Points:
One primary goal of programming is managing complexity.
The programming process significantly affects the final product.
Team programming is more an exercise in communicating with people than in communicating with a computer. Individual programming is more an exercise in communicating with yourself than with a computer.
When abused, a programming convention can be a cure that’s worse than the disease. Used thoughtfully, a convention adds valuable structure to the development environment and helps with managing complexity and communication.
Programming in terms of the problem rather than the solution helps to manage complexity.
Paying attention to intellectual warning signs like the “irritation of doubt” is especially important in programming because programming is almost purely a mental activity.
The more you iterate in each development activity, the better the product of that activity will be.
Dogmatic methodologies and high-quality software development don’t mix. Fill your intellectual toolbox with programming alternatives and improve your skill at choosing the right tool for the job.