People have been writing programs for electronic computers for more than 80 years, but there has been surprisingly little conversation about how to design those programs or what good programs should look like. There has been considerable discussion about software development processes such as agile development and about development tools such as debuggers, version control systems, and test coverage tools. There has also been extensive analysis of programming techniques such as object-oriented programming and functional programming, and of design patterns and algorithms. All of these discussions have been valuable, but the core problem of software design is still largely untouched. David Parnas’ classic paper 「On the Criteria to be used in Decomposing Systems into Modules」 appeared in 1971, but the state of the art in software design has not progressed much beyond that paper in the ensuing 45 years.程序員
人類經過電腦編程已經有 80 年的歷史了,可是使人震驚的是,關於如何進行軟件設計、好的軟件到底是怎樣的的對話居然如此之少。關於開發進度控制的討論有至關多,包含敏捷開發、開發工具好比調試器、版本控制系統、測試覆蓋工具等。大範圍的關於面向對象編程、函數式、設計模式、算法的分析也很多。這些討論都頗有價值,可是軟件設計的核心問題仍未被涉及。David Parnas 的經典論文《系統分解成模塊的標準》發表於 1971,可是關於軟件設計的藝術的描述,自從 45 年前被這篇論文說起以來,並無多大的進步。
The most fundamental problem in computer science is problem decomposition: how to take a complex problem and divide it up into pieces that can be solved independently. Problem decomposition is the central design task that programmers face every day, and yet, other than the work described here, I have not been able to identify a single class in any university where problem decomposition is a central topic. We teach for loops and object-oriented programming, but not software design.算法
計算機科學最基礎的問題,是複雜度控制:如何把複雜問題分解成能夠被解決的小塊。複雜度控制是程序員天天都要面對的核心任務。可是除了如今對這個話題的討論,我歷來沒有見過大學裏有一門課教授這個話題。咱們教授循環語句和麪向對象,可是不教軟件設計。
In addition, there is a huge variation in quality and productivity among programmers, but we have made little attempt to understand what makes the best programmers so much better or to teach those skills in our classes. I have talked with several people I consider to be great programmers, but most of them had difficulty articulating specific techniques that give them their advantage. Many people assume that software design skill is an innate talent that cannot be taught. However, there is quite a bit of scientific evidence that outstanding performance in many fields is related more to high-quality practice than innate ability (see, for example, Talent is Overrated by Geoff Colvin).編程
另外,程序員之間的產出質量和效率之間有巨大的差別,可是咱們卻少有嘗試去理解爲何最好的程序員,在技巧上比咱們課堂上的各位強這麼多。我跟一些厲害的程序員交流過,可是他們大多數並不能準確描述,是哪些技能讓他們得到優點的。不少人以爲軟件設計能力是一項天賦,是不能傳授的。然而,大量的科學證據代表,在多個領域中的出色表現,高質量的練習的相關性比天生的才能更多。(能夠看看 Geoff Colvin 的《被高估的天賦》)
For many years these issues have perplexed and frustrated me. I have wondered whether software design can be taught, and I have hypothesized that design skill is what separates great programmers from average ones. I finally decided that the only way to answer these questions was to attempt to teach a course on software design. The result is CS 190 at Stanford University. In this class I put forth a set of principles of software design. Students then work through a series of projects to assimilate and practice the principles. The class is taught in a fashion similar to a traditional English writing class. In an English class, students use an iterative process where they write a draft, get feedback, and then rewrite to make improvements. In CS 190, students develop a substantial piece of software from scratch. We then go through extensive code reviews to identify design problems, and students revise their projects to fix the problems. This allows students to see how their code can be improved by applying design principles.設計模式
多年來這些問題一直讓我困惑沮喪。我有考慮過軟件設計是否能被教授,曾經也假設過是否擁有設計的技巧,就是區分偉大程序員與普通程序員的指標。最後我決定嘗試經過開設軟件設計課程這種方式,來嘗試解開這個問題。結果就是 CS 190 這門課在斯坦福大學誕生了。在這門課裏,我提出了一系列軟件設計的準則。學生們能夠經過一系列的項目去理解和實踐這些準則。這門課以一種相似於傳統英語寫做的時尚方式,學生反覆地進行打草稿、得到反饋、重構優化。他們從頭開始學習軟件設計中極爲重要的一環。而後咱們經過大量的代碼評審,去認識設計問題,再讓學生修正項目。這種方式讓學生們看到,應用這些準則後,他們的代碼是如何獲得改進的。
I have now taught the software design class three times, and this book is based on the design principles that emerged from the class. The principles are fairly high level and border on the philosophical (「Define errors out of existence」), so it is hard for students to understand the ideas in the abstract. Students learn best by writing code, making mistakes, and then seeing how their mistakes and the subsequent fixes relate to the principles.app
現在我已經教授這門課 3 次了,並把其中總結到的設計準則做爲這本書的根基。這些準則在哲學層面上(定義不存在的問題),水平高而且廣度大。因此對於學生來講很難在抽象層面去理解這些思想。最好的學習方式是經過編寫代碼,而後犯錯,最後看看這些準則如何與修正錯誤是相關的。
At this point you may well be wondering: what makes me think I know all the answers about software design? To be honest, I don’t. There were no classes on software design when I learned to program, and I never had a mentor to teach me design principles. At the time I learned to program, code reviews were virtually nonexistent. My ideas about software design come from personal experience writing and reading code. Over my career I have written about 250,000 lines of code in a variety of languages. I’ve worked on teams that created three operating systems from scratch, multiple file and storage systems, infrastructure tools such as debuggers, build systems, and GUI toolkits, a scripting language, and interactive editors for text, drawings, presentations, and integrated circuits. Along the way I’ve experienced firsthand the problems of large systems and experimented with various design techniques. In addition, I’ve read a considerable amount of code written by other people, which has exposed me to a variety of approaches, both good and bad.electron
到這裏也許你就疑惑了:是什麼讓我以爲我掌握了軟件設計的全部答案?老實說,我沒有掌握。我當初學習編程的時候,沒有軟件設計這門課,也沒有導師叫我設計準則。我學編程那會代碼評審甚至還沒誕生。個人那些關於軟件設計的思想,來自於編寫和閱讀代碼的經驗。職業生涯中,我編寫了 250,000 行代碼,用過多種語言。我曾經在從頭開始設計過 3 種操做系統的團隊裏工做過,設計過文件存儲系統、基礎開發工具好比調試器、構建系統、GUI 工具包、一種腳本語言、文本的交互式編輯器、繪畫、幻燈片、集成電路。一路走來,我親身經歷了大量大型系統的問題,並實踐過多種設計技術。另外,我還閱讀過很是大量的別人寫的代碼,從中接觸到了各類各樣的方法,有好的也有壞的。
Out of all of this experience, I’ve tried to extract common threads, both about mistakes to avoid and techniques to use. This book is a reflection of my experiences: every problem described here is one that I have experienced personally, and every suggested technique is one that I have used successfully in my own coding.編輯器
從全部的經驗中,我嘗試從中提取出共同點,包括要避免的錯誤和要實行的技巧。這本書就是個人經驗的反映:書中的每一個問題都是我親身經歷的,每一個提議的技巧都是我親自在編碼中成功實踐過的。
I don’t expect this book to be the final word on software design; I’m sure there are valuable techniques that I’ve missed, and some of my suggestions may turn out to be bad ideas in the long run. However, I hope that the book will start a conversation about software design. Compare the ideas in this book with your own experiences and decide for yourself whether the approaches described here really do reduce software complexity. This book is an opinion piece, so some readers will disagree with some of my suggestions. If you do disagree, try to understand why. I’m interested in hearing about things that work for you, things that don’t work, and any other ideas you may have about software design. I hope that the ensuing conversations will improve our collective understanding of software design. I will incorporate what I learn in future editions of this book.ide
我不認爲這本書是軟件設計的最終答案,我十分肯定還有重要的技巧被我遺漏了,還有,一些建議從長遠看來也許並很多好主意。但我仍是但願這本書能開啓關於軟件設計的討論。用書中的想法與你的實際經驗去比較,再去看看這些方法是否減小了軟件複雜度。這本書只是一些我的意見,確定會有人不一樣意當中的一些見解。若是你也不一樣意,請理解一下其中的原因。我很想聽聽哪些對你有用,哪些沒有,還有你對於軟件設計的見解。我但願後續的討論能促進咱們對軟件設計的集體理解,我也會在這本書的後續版本中增長我進一步的學習成果。
The best way to communicate with me about the book is to send email to the following address:
software-design-book@googlegroups.com函數
要與我討論書中的內容,最好的方式就是發送到如下郵箱:
I’m interested in hearing specific feedback about the book, such as bugs or suggestions for improvement, as well as general thoughts and experiences related to software design. I’m particularly interested in compelling examples that I can use in future editions of the book. The best examples illustrate an important design principle and are simple enough to explain in a paragraph or two. If you would like to see what other people are saying on the email address and participate in discussions, you can join the Google Group software-design-book.工具
我十分歡迎關於這本書的具體的反饋,好比 BUG 或者改進的建議,還有關於軟件設計的通常思想和經驗。特別是引人注目的實際例子,這樣我就能把它加入到書的再版中。最好例子能闡述一個重要的設計準則,而且能用一兩句話就能描述清楚了。若是你想看看其餘人在這個郵件地址裏說什麼,討論什麼,能夠加入 software-design-book 谷歌小組。
If for some reason the software-design-book Google Group should disappear in the future, search on the Web for my home page; it will contain updated instructions for how to communicate about the book. Please don’t send book-related email to my personal email address.
若是某種緣由致使這個小組消失了,請搜索個人主頁,裏面會更新探討這本書的聯繫方式。請不要發送到個人我的郵箱。
I recommend that you take the suggestions in this book with a grain of salt. The overall goal is to reduce complexity; this is more important than any particular principle or idea you read here. If you try an idea from this book and find that it doesn’t actually reduce complexity, then don’t feel obligated to keep using it (but, do let me know about your experience; I’d like to get feedback on what works and what doesn’t).
我建議你從聽取書中的提議的時候,持保留態度。由於總體來講,目的是減小複雜度,這比任何一個你從中讀到的特定的指標都要重要。若是用了書中的思想,而後發現複雜度並未實質性地減小,那就不須要再以爲仍有義務去使用它(可是還請通知我關於你的經歷,由於我得到哪些有用哪些沒有的反饋)。
Many people have offered criticisms or made suggestions that improved the quality of the book. The following people offered helpful comments on various drafts of the book: Jeff Dean, Sanjay Ghemawat, John Hartman, Brian Kernighan, James Koppel, Amy Ousterhout, Kay Ousterhout, Rob Pike, Partha Ranganathan, Keith Schwartz, and Alex Snaps. Christos Kozyrakis suggested the terms 「deep」 and 「shallow」 for classes and interfaces, replacing previous terms 「thick」 and 「thin」, which were somewhat ambiguous. I am indebted to the students in CS 190; the process of reading their code and discussing it with them has helped to crystallize my thoughts about design.
已經有不少人爲這本書提供了建議或者批評,來提高本書的質量。如下這些朋友爲初稿提供了有用的評價:Jeff Dean, Sanjay Ghemawat, John Hartman, Brian Kernighan, James Koppel, Amy Ousterhout, Kay Ousterhout, Rob Pike, Partha Ranganathan, Keith Schwartz, 還有 Alex Snaps。Christos Kozyrakis 建議使用詞語「深度的」和「淺層的」,代替以前有些模糊的詞彙「厚的」和「薄的」。我對 CS 190 班的學生們深表感激,閱讀和討論他們的代碼的過程,幫助我驗證了關於設計的想法。