本书直击编程阵地,穿过了日益增长的现代软件开发的规范和学术,对核心过程进行了审视——该过程采取了供需结合的工作方式和令人欣喜的可维护代码。本书包含的内容从个人责任和职业发展到保持代码的灵活性,使之易于改编和重用。\r\n阅读本书,读者将学到:\r\n·防止软件变质;\r\n·消除复制知识的陷阱;\r\n·编写灵活、动态和易适应的代码;\r\n·比买内出现相同的设计;\r\n·用契约、断言和异常对代码进行防护;\r\n·洞察真正需求;\r\n·严格高效地进行测试;\r\n·取悦用户的方法;\r\n·组建实用性编程者队伍;\r\n·用自动化使开发过程更精确。\r\n\r\n 本书由各个相对独立的章节组成,其间不乏好玩的轶事、详细的实例和有趣的对话,描述了软件开发各个方面的最好实践和主要缺陷。无论你是一个新入门的编码者、一个有经验的程序员,还是负责软件项目的经理,通过每日学习这些课程,都会在个人生产力、准确率和工作满意度上有快速的增长。你所学到的技巧和开发习惯和态度将为你在职业生涯中取得长期成功奠定基础。你将成为又一Pragmatic Programmer。
Contents\r\n\r\n1The Cat Ate My Source Code 2\r\n2SoftwareEntropy4\r\n3Stone Soup and Boiled Frogs 7\r\n4Good-Enough Software 9\r\n5Your Knowledge Portfolio 12\r\n6Communicate! 18\r\n7The Evils ofDuplication 26\r\n8Orthogonality 34\r\n9Reversibility 44\r\n10Tracer Bullets 48\r\n11Prototypes and Post-it Notes 53\r\n12Domain Languages 57\r\n13Estimating 64\r\n14The Power of Plain Text 73\r\n15Shell Games 77\r\n16Power Editing 82\r\n17Source Code Control 86\r\n18Debugging 90\r\n19TextManipulation 99\r\n20Code Generators 102\r\n21Design by Contract 109\r\n22Dead Programs Tell No Lies 120\r\n23Assertive Programming 122\r\n24When toUse Exceptions 125\r\n25How to Balance Resources 129\r\n26Decoupling and the Law of Demeter 138\r\n27Metaprogramming 144\r\n28Temporal Coupling 150\r\n29It’s Just a View 157\r\n30Blackboards 165\r\n31Programming by Coincidence 172\r\n32AlgorithmSpeed 177\r\n33Refactoring 184\r\n34Code That’s Easy to Test 189\r\n35EvilWizards 198\r\n36The Requirements Pit 202\r\n37Solving Impossible Puzzles 212\r\n38Not Until You’re Ready 215\r\n39The Specification Trap 217\r\n40Circles and Arrows 220\r\n41Pragmatic Teams 224\r\n42Ubiquitous Automation 230\r\n43Ruthless Testing 237\r\n44It’s AllWriting 248\r\n45Great Expectations 255\r\n46Pride and Prejudice 258\r\nProfessional Societies 262\r\nBuilding a Library 262\r\nInternet Resources 266\r\nBibliography 275
This book will help you become a better programmer.
It doesn't matter whether you are a lone developer, a member of a large project team, or a consultant working with many clients at once. This book will help you, as an Individual, to do better work. TbAs book isn't theoretical--we concentrate on practical topics, on usIng your experience to make more Informed decisions. The word pragmatic comes from the Latin pragmat/cus--"skfiled in business"--which itseff is derived from the Greek, meaning "to do." This is a book about doing.
Programming is a craft. At its simplest, it comes down to getting a computer to do what you want it to do (or what your user wants it to do). As a programmer, you are part listener, part advisor, part Interpreter, and part dictator. You try to capture elusive requirements and find a
way of expressIng them so that a mere machine can do them Justice. You try to document your work so that others can understand it, and you try to engineer your work so that others can build on it. What's more, you try to do all this against the relentless ticking of the project clock. You work small miracles every day. It's a difficult Job.
There are many people offering you help. Tool vendors tout the miracles their products perform. Methodology gurus promise that their techniques guarantee results. Everyone claims that their programming language is the best, and every operating system is the answer to all conceivable ills.
Of course, none of this is true. There are no easy answers. There is no such thing as a best solution, be it a tool, a language, or an operating system. There can only be systems that are more appropriate In a particular set of circumstances.
This is where pragmatism comes in. You shouldn't be wedded to any particular technology, but have a broad enough background and experience base to allow you to choose good solutions in particular situations. Your background stems from an understanding of the basic principles of computer science, and your experience comes from a wide range of practical projects. Theory and practice combine to make you strong.
You adjust your approach to suit the current circumstances and environment. You Judge the relative importance of all the factors affecting a project and use your experience to produce appropriate solutions. And you do this continuously as the work progresses. Pragmatic Program-
mers get the job done, and do it well.
Who Should Read This Book?
This book is aimed at people who want to become more effective and more productive programmers. Perhaps you feel frustrated that you don't seem to be achieving your potential. Perhaps you look at colleagues who seem to be using tools to make themselves more productive than you. Maybe your current job uses older technologies, and you want to know how newer ideas can be applied to what you do.
We don't pretend to have all (or even most) of the answers, nor are all of our ideas applicable in all situations. All we can say is that ff you follow our approach, you'll gain experience rapidly, your productivity will increase, and you'll have a better understanding of the entire
development process. And you'll write better software.
What Makes a Pragmatic Programmer?
Each developer is unique, with individual strengths and weaknesses, preferences and dislikes. Over time, each will craft his or her own personal environment. That environment will reflect the programmer's individuality just as forcefully as his or her hobbies, clothing, or hair-cut. However, if you're a Pragmatic Programmer, you'll share many of
the following characteristics:
Early adopter/fast adapter. You have an instinct for technologies and techniques, and you love trying things out. When given something new, you can grasp it quickly and integrate it with the rest of your knowledge. Your confidence is born of experience.
Inquisitive. You tend to ask questions. That's neat--how did you do that? Did you have problems with that library? What's this BeOS I've heard about? How are symbolic links implemented? You are a pack rat for little facts, each of which may affect some decision years from now.
Critical thinker. You rarely take things as given without first getting the facts. When colleagues say 'because that's the way it's done," or a vendor promises the solution to all your problems, you smell a challenge.
Realistic. You try to understand the underlying nature of each problem you face. This realism gives you a good feel for how difficult things are, and how long things will take. Understanding for yourseff that a process should be difficult or will take a while to complete gives you the stamina to keep at lt.
Jack of all trades. You try hard to be familiar with a broad range of technologies and environments, and you work to keep abreast of new developments. Although your current job may require you to be a specialist, you will always be able to move on to new areas and new challenges.
We've left the most basic characteristics until last. All Pragmatic Programmers share them. They're basic enough to state as tips: We feel that there is no point in developing software unless you care about doing it well.
In order to be a Pragmatic Programmer, we're challenging you to think about what you're doing while you're doing it. This isn't a one-time audit of current practices---it's an ongoing critical appraisal of every decision you make, every day, and on every development. Never run on
auto-pilot. Constantly be thinking, critiquing your work in real time. The old IBM corporate motto, THINK!, is the Pragmatic Programmer's mantra.
If this sounds like hard work to you, then you're exhibiting the rea//st/c characteristic. This is going to take up some of your valuable time--time that is probably already under tremendous pressure. The reward is a more active involvement with a job you love, a feeling of mastery over
an increasing range of subjects, and pleasure in a feeling of continuous improvement. Over the long term, your time investment will be repaid as you and your team become more efficient, write code that's easier to maintain, and spend less time in meetings.
Individual Pragmatists, Large Teams
Some people feel that there is no room for individuality on large teams or complex projects. "Software construction is an engineering discipline," they say, "that breaks down ff individual team members make decisions for themselves."
We disagree.
The construction of software should be an engineering discipline. However, this doesn't preclude individual craftsmanship. Think about the large cathedrals built in Europe during the Middle Ages. Each took thousands of person-years of effort, spread over many decades. Lessons learned were passed down to the next set of builders, who advanced the state of structural engineering with their accomplishments. But the carpenters, stonecutters, carvers, and glass workers were all craftspeople, interpreting the engineering requirements to produce a whole that transcended the purely mechanical side of the construction. It was their belief in their individual contributions that sustained the projects:
We who cut mere stones must always be envisioning cathedrals. Quarry worker's creed
Within the overall structure of a project there is always room for individuality and craftsmanship. This is particularly true given the current state of software engineering. One hundred years from now, our engineering may seem as archaic as the techniques used by medieval
cathedral builders seem to today's civil engineers, while our craftsman-ship will still be honored.
It's a Continuous Process
A tourist visiting England's Eton College asked the gardener how he got the lawns so perfect. "That's easy," he replied, "You just brush off the dew every morning, mow them every other day, and roll them once a week. "
"Is that all?" asked the tourist.
"Absolutely," replied the gardener. "Do that for 500 years and you'll have a nice lawn, too." Great lawns need small amounts of daily care, and so do great programmers. Management consultants like to drop the word kaizen in conversations. "Kaizen" is a Japanese term that captures the concept of continuously making many small improvements. It was considered to be one of the main reasons for the dramatic gains in productivity and quality in Japanese manufacturing and was widely copied throughout the world. Kaizen applies to individuals, too. Every day, work to refine
the skills you have and to add new tools to your repertoire. Unlike the Eton lawns, you'll start seeing results in a matter of days. Over the years, you'll be amazed at how your experience has blossomed and your skills have grown.
How the Book Is Organized
This book is written as a collection of short sections. Each section is self-contained, and addresses a particular topic. You'll find numerous cross references, which help put each topic in context. Feel free to read the sections in any order--this isn't a book you need to read front-to-back.
Occasionally you'll come across a box labeled Tip nn (such as Tip 1,"Care About Your Craft" on page xix). As well as emphasizing points in the text, we feel the tips have a life of their own--we live by them daffy. You'll find a summary of all the tips on a pull-out card inside the back cover.
Appendix A contains a set of resources: the book's bibliography, a list of URLs to Web resources, and a list of recommended periodicals, books, and professional organizations. Throughout the book you'll find references to the bibliography and to the list of URLs---such as [KP99] and
[URL 18], respectively. We've included exercises and challenges where appropriate. Exercises
normally have relatively straightforward answers, while the challenges are more open-ended. To give you an idea of our thinking, we've included our answers to the exercises in Appendix B, but very few have a single correct solution. The challenges might form the basis of group discussions or essay work in advanced programming courses.
What's in a Name?
"When I use a word," Humpty Dumpty said, in rather a scornful tone, "it means just what I choose it to mean--neither more nor less."
Carroll, Through the Looking-Glass
Scattered throughout the book you'll find various bits of jargon--either perfectly good English words that have been corrupted to mean something technical, or horrendous made-up words that have been assigned meanings by computer scientists with a grudge against the language. The first time we use each of these jargon words, we try to define it, or at least give a hint to its meaning. However, we're sure that some have fallen through the cracks, and others, such as object and relational database, are in common enough usage that adding a definition would be boring. If you do come across a term you haven't seen before, please don't just skip over it. Take time to look it up, perhaps on the Web, or maybe in a computer science textbook. And, if you get a chance, drop us an e-mail and complain, so we can add a definition to the next edition.
Having said all this, we decided to get revenge against the computer scientists. Sometimes, there are perfectly good jargon words for concepts, words that we've decided to ignore. Why? Because the existing jargon is normally restricted to a particular problem domain, or to a particular phase of development. However, one of the basic philosophies of this book is that most of the techniques we're recommending are universal: modularity applies to code, designs, documentation, and team organization, for instance. When we wanted to use the conventional
Jargon word in a broader context, it got confusing-we couldn't seem to overcome the baggage the original term brought with it. When this happened, we contributed to the decline of the language by inventing our own terms.
Source Code and Other Resources
Most of the code shown in this book is extracted from compfiable source files, available for download from our Web site:
www.pragmat icprogr ammer.c om
There you'll also find links to -resources we find useful, along with updates to the book and news of other Pragmatic Programmer developments.
Send Us Feedback
We'd appreciate hearing from you. Comments, suggestions, errors in the text, and problems in the examples are all welcome. E-mail us at
ppbook@pragmaticprogrammer, com
Acknowledgments
When we started wriUng this book, we had no idea how much of a team effort it would end up being.
Addison-Wesley has been brilliant, taking a couple of wet-behind-the-ears hackers and walking us through the whole book-production process, from idea to camera-ready copy. Many thanks to John Wait and Meera Ravindiran for their initial support, Mike Hendrickson, our enthusiastic editor (and a mean cover designer!), Lorraine Ferrier and John Fuller for their help with production, and the indefatigable Julie DeBaggis for keeping us all together.
Then there were the reviewers: Greg Andress, Mark Cheers, Chris Clee land, Alistair Cockburn, Ward Cunningham, Martin Fowler, Thanh T. Glang, Robert L. Glass, Scott Henninger, Michael Hunter, Brian Kirby, John Lakos, Pete McBreen, Carey P. Morris, Jared Richardson, Kevin Ruland, Eric Starr, Eric Vought, Chris Van Wyk, and Deborra Zukowski. Without their careful comments and valuable insights, this book would be less readable, less accurate, and twice as long. Thank
you all for your time and wisdom.
The second printing of this book benefited greatly from the eagle eyes of our readers. Many thanks to Brian Blank, Paul Boal, Tom Ekberg, Brent Fulgham, Louis Paul Hebert, Henk-Jan Olde Loohuis, Alan Lund, Gareth McCaughan, Yoshiki Shibata, and Volker Wurst, both for find-
ing the mistakes and for having the grace to point them out gently. Over the years, we have worked with a large number of progressive clients, where we gained and refined the experience we write about here. Recently, we've been fortunate to work with Peter Gehrke on sev-
eral large projects. His support and enthusiasm for our techniques are much appreciated.
This book was produced using LATEX, pic, Perl, dvips, ghostview, ispell, GNU make, CVS, Emacs, XEmacs, EGCS, GCC, Java, iContract, and SmaUEiffel, using the Bash and zsh shells under Linux. The staggering thing is that all of this tremendous software is freely available. We
owe a huge "thank you" to the thousands of Pragmatic Programmers worldwide who have contributed these and other works to us all. We'd particularly like to thank Reto Kramer for his help with iContract. Last, but in no way least, we owe a huge debt to our famfiies. Not only have they put up with late night typing, huge telephone bills, and our permanent air of distraction, but they've had the grace to read what we've written, time after time. Thank you for letting us dream.
Andy Hunt
Dave Thomas