A Software Developer’s Reading List

“An investment in knowledge always pays the best interest.” – Benjamin Franklin

Many of the best software developers have T-Shaped Skills: Deep expertise in programming and software development, and broad knowledge of diverse areas including testing, DevOps, UX design, team organization, customer interaction, and their domain areas. While there is unfortunately no substitute for experience, reading is probably the next best thing. Over the past 10 years I’ve read a lot in an effort to deepen and broaden my knowledge as a software developer. Along the way I’ve been organizing books and concepts into the reading list I share below. I have been trying to design a core curriculum for “modern” software development by asking myself:

  • What core concepts are required to be a world class software developer?
  • What is the best book for introducing and teaching each concept?

The result is a list of 16 essential software development concepts presented by 16 excellent books…

Methodology & Other Notes (skip to reading list)

Reading a book is a significant time investment, so I don’t recommend a book lightly. In order to design an effective and efficient reading list, I have tried to structure it around a concept list satisfying these criteria:

  • Complete: Don’t omit necessary concepts.
  • Essential: Don’t include optional concepts. Concepts should be relevant to most developers during their career.
  • Non-redundant: Limit overlap and repetitive content.
  • Universal: Technology & domain independent.
  • Applied, not Theoretical: So this list excludes great theoretical books like Gödel, Escher, Bach.
  • Software Development, not Programming: The distinction is quite fuzzy, but I think of programming as getting a computer to do what you want and software development as evolving valuable software with a team. Learning programming deserves an entirely different reading list (like this one). Every programming reading list should include Code CompleteSICP, and this article: Teach Yourself Programming in 10 years. (If you are learning programming, you may be interested to peruse my notes about Why & How I Write Java.)
  • Software Development, not Computer Science: (The following observations are not a consensus. They are my opinions based on my experience which includes being a computer science teaching assistant for C++, assembly, logic design, algorithms, databases, and artificial intelligence, followed by 7 years of professional software development.) There is limited overlap between a professional software development (SD) curriculum and a traditional computer science (CS) curriculum. A computer science degree often includes learning programming plus courses including automata theory, algorithms, programming language theory, operating systems, networking, cryptography, databases, artificial intelligence, logic design, hardware architecture, etc. A functional understanding of algorithms, data structures, and complexity (big O) is important for programming. A CS database course provides a theoretical foundation for the broader SD challenge of data management in practice. Other than algorithms and databases, I’ve found many CS subjects to be optional (but occasionally helpful) for many kinds of software development. In some areas of SD a background in UX design or domain knowledge might actually be more helpful than CS.

Other notes:

  • Beyond listing the 16 core books for each concept, this page also include notes, links to further worthwhile reading, and related quotes. Some of the notes may not be useful until after reading the book for context.
  • I also link to other reading lists at the bottom of this page.
  • I prefer books with human narrative over a lofty academic writing style. I find that staying awake significantly improves my reading comprehension.
  • The book links are to Amazon where you can read reviews and view the table of contents by clicking on the book image. I assume many are available as eBooks. Some are also available online as PDFs.
  • My software development experience has mostly been in small startups delivering web applications and web services implemented in Java, Python, and JavaScript. As with any point of view, my experience informs this reading list while also biasing it.
  • By its nature this is an evolving list. I would love your feedback about the concept list, the book selections, my concept notes, and any worthwhile books or quotes that I’ve missed. Thanks!

Outline: A Software Developer’s Reading List

Software Creation Concepts
1Test-Driven DevelopmentGrowing Object-Oriented Software, Guided By Tests
2RefactoringRefactoring

Software Design Concepts
3. Code DesignClean Code
4. Component Design (Object-Oriented): Object Design
5. Domain Design: Domain Driven Design
6. System Design: Software Systems Architecture
7. System Design (Availability): Release It!
8. System Design (Security): Foundations of Security
9. Legacy Code: Working Effectively With Legacy Code
10. User Experience Design: Designing Interfaces

Software Delivery Concepts
11. Lean Systems: Leading Lean Software Development
12. Agile Team Organization: Essential Scrum
13. Requirements Design: User Stories Applied
14. Testing Products & Services: Agile Testing
15. Continuous Delivery: Continuous Delivery
16. Customer Development: Lean Startup

Reading List

16 books, 16 inches, 27 pounds, 6543 pages

I believe these 16 books are a great start for any professional software developer (after learning programming). It is certainly a much more direct path than I took. By no means are these the only excellent books or the only books you should read. This list is simply the most effective and efficient overview I know how to recommend. The “Further Reading” sections contain many important and classic books.

The reading list begins with 2 basic software evolution skills: Test-Driven Development and Refactoring. Next are 4 different levels of software design granularity: Code Design, Component Design, Domain Design, and System Design. We then expand on System Design by digging into 2 commonly important system qualities: Availability and Security. We round out Software Design with 2 more perspectives: Legacy Code and User Experience Design. Next are the 6 Software Delivery concepts present how to organize tools & teams to successfully deliver valuable software to customers and users.

I have tried to place the books in a natural sequence, but I would read them in whatever order makes sense for you and your work. Many of these books are worth reading cover to cover, but some have sections you can safely skip or defer. (Perhaps keep in mind that if you have time to read 1000 pages, reading 200 pages of 5 books is often worth more than reading 500 pages of 2 books.)

New concepts based on feedback
I think it’s important to keep this list to a manageable size, however based on feedback, I will probably be adding 4 concepts:

  • Professional Craft: Software development is a craft. This has implications for how it is learned and what constitutes professional conduct. The classic book here would be The Pragmatic Programmer.
  • Component Design (Functional): I want to split Component Design into Component Design (Object-Oriented) and Component Design (Functional). It looks like Functional Thinking may be the right functional book when it is released (earlier articles and presentation by the author).
  • Data Management: This is a core skill that is missing from the 16 concepts. I’m not sure what book to use. Subjects include relational vs. key-value, normalization vs. performance, transactions, big data, sharding, consistency, distribution, UUIDs, backup+recovery, scaling, schema evolution, etc. One option is a computer science textbook like Database Systems, but I worry about this choice because there is a sizable gap between theory and practice in this area.
  • Managing Humans: Peopleware is the classic book (3rd edition in 2013). I stole the concept name from the book Managing Humans, which will be in the further reading section (along with the associated blog Rands in Repose). I would also include a link to this article.

Software Creation Concepts (#1-2)

1. Test-Driven Development: Writing automated tests to discover requirements, guide software design, enable refactoring, and prevent regressions.

Concept notes (this concept has more notes than the others):

  • Testing software early is important for many reasons:
    • The cost of an undetected defect rises dramatically over time. Once automated tests are in place we find many bugs shortly after they are introduced, so we easily know what changes caused the problem.
    • Writing tests helps us understand (and often discover) the detailed requirements.
    • Tests enable us to improve the design of software via refactoring. The fear of changing untested software is worth experiencing: it fosters intrinsic motivation for testing.
    • Testing improves modularity by forcing us to invert dependencies (statically depend on interfaces, not implementations).
    • Tests provide executable requirements documentation, enabling us to write less textual documentation (trust code, not comments).
    • Tests force us to support a 2nd client: production is the 1st, and the test is the 2nd. A 2nd example provides valuable design feedback.
    • Testing guides us to write testable code. Untested code is often untestable. You end up with coupled Legacy Code.
  • When practicing Test-Driven Development you write tests before implementing the functionality:
    1. Before adding a new capability or fixing a bug, write a failing test.
    2. Make the test pass in the easiest conceivable way. Don’t plan much; design as little as possible; just get the test passing. If the implementation is embarrassing (but passing), you’re doing well at this point.
    3. Under the cozy protection of a passing test, refactor the implementation until it is “reasonably clean“.
  • There are many types of software testing including unit testing, integration testing, acceptance testing, system testing, regression testing, smoke testing, non-functional testing, stress testing, performance testing, usability testing, etc. Unit testing is the foundation. Here is a comparison of unit, integration, functional, and acceptance.
  • Most pieces of software (i.e. units, components, systems) use and depend on other pieces software. These other pieces of software are the dependencies. An important part of testing software is deciding what implementation to choose for dependencies during testing. For example, if you were persisting Account objects you would use (depend on) a database. Let’s say you use a MySQL database implementation in production. If you also use MySQL in your unit tests, you will often find that it is too slow and inconvenient. Instead you will want to use an in-memory database when running unit tests. This in-memory database is an example of a Test Double, or more specifically a Fake Object. With vocabulary derived from Mocks aren’t Stubs and the xUnit Test Patterns (table), here are several options for dependency implementations:
    • Real Dependency: Using the same implementation in tests as in production. (MySQL in the example.)
    • Test Double: Using a different implementation in tests:
      • Fake Object: A different but fully functional implementation (in-memory database in the example)
      • Dummy Object: An object that is passed around, but is never used by the code we’re testing (i.e. providing null, knowing it doesn’t matter)
      • Stub Object: An object that provides canned (hardcoded) answers to method calls.
      • Mock Object: From wikipedia, a mock is a simulated object that mimics the behavior of real objects in controlled ways. This is an extremely flexible Test Double, but the tradeoff is your test ends up knowing implementation details of the code you’re testing (coupling the two). For this reason I use fakes instead of mocks whenever possible. My favorite mocking library for Java is Mockito. (When deciding between mocks and fakes, perhaps also consider that mocks nail down behavior where fakes may only nail down end state. If you loop through rows in a database instead of doing one large query, the final state might be correct, but the looping implementation may be a behavioral bug causing inefficiency. In this case the test may want to verify the implementation details, despite the reduced modularity between test and code-under-test.)
  • In order to use a Test Double implementation for a dependency, that dependency must be inverted. Instead of statically importing an implementation (i.e. class or instance), the implementation should be provided at runtime, often as a constructor parameter. In a language with interfaces you would statically import the interface. By inverting the dependency, the test is able to provide a Test Double (i.e. in-memory database) while production provides the Real Dependency (i.e. MySQL database). It think it is fair to say that the unavoidable price of testability is dependency inversion. The family of mechanisms used to provide dependencies at runtime is sometimes called Dependency Injection.

Further reading:

Related quotes:

2. Refactoring: Evolving the design of software.

Concept notes:

Further reading:

Related quotes:

  • “The best writing is rewriting.” – E. B. White (The Elements of Style)
  • “No great thing is created suddenly.” – Epictetus
  • “Before software can be reusable it first has to be usable.” – Ralph Johnson (GoF)
  • “He who rejects change is the architect of decay.” – Harold Wilson
  • “I made this letter longer than usual because I lack the time to make it shorter.” – Blaise Pascal
  • “We tried to add the feature to our application but found that there was no place for it. So we first made a place, and then added the feature there.” – Ward Cunningham (Invented Wikis, Technical Debt, Agile Manifesto)
  • “Creativity is allowing yourself to make mistakes. Design is knowing which ones to keep.” – Scott Adams (Dilbert)
  • “It’s about whittling. It’s about taking something and whittling and whittling and getting it sharp and perfect. Then you’ve got something.” – James Victore
  • “Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.” – Antoine de Saint-Exupéry

Software Design Concepts (#3-10)

3. Code Design: Writing intention revealing code.

Concept notes:

  • Professional code is written for humans to read. It is a communication medium. (The code itself, not just comments. Comment the why; the code should make what and how evident.) The person reading a developer’s code may be their teammate, or it may be themselves months or years from now. Coding is like writing or speaking: we learn what minimum level of clarity is necessary to communicate successfully. We meet this baseline of clarity even when we’re in a hurry (i.e. email, voicemail, rapid prototype). When the message is important we put extra effort into clarity (i.e. essay, speech, reusable library). The reality is that if someone is incoherent then nobody will want to listen to them (or work with them).
  • I feel that programming becomes software development when you collaborate with a team on a shared codebase. For a team to avoid accidental complexity, established standards should often take precedence over personal preferences, with all team members helping to guide what those standards should be. Pair programming is a great way to discuss, debate, and share such standards.

Further reading:

Related quotes:

4. Component Design (Object-Oriented): Managing interfaces to manage complexity.

(Update: When I do a full revision of this reading list, I think I’m going to switch my top recommendation in this category to Practical Object-Oriented Design in Ruby.)

Concept notes:

  • There are many great Component Design books, and it’s definitely worth reading several in this area. To get started I recommend Object Design because I think roles, responsibilities, and collaborations are at the heart of the matter, and because it reads like a human narrative. (One aspect of this book I’m unsure of is CRC cards because I’ve never tried them.)
  • Here is a mental model I’ve developed over time for how a bunch of component design principles (heuristics) relate to each other.
  • As a programming subject, the dichotomy between Functional Programming and Object-Oriented Programming isn’t addressed in this software development focused reading list. That being said, mutation and side-effects are complexity creating monsters. I believe that regardless of the implementation language, the best software designers apply functional principles when possible. I’ve never used a functional language in production, but I’ve benefited enough from these functional principles to consider them beyond doubt:

Further reading:

Related quotes:

  • “Fools ignore complexity; pragmatists suffer it; experts avoid it; geniuses remove it.” – Alan Perlis (Turing Award #1, ALGOL)
  • “Computer Science is the first engineering discipline in which the complexity of the objects created is limited solely by the skill of the creator, and not by the strength of raw materials.” – Brian Reid (Grace Murray Hopper Award)
  • “The competent programmer is fully aware of the strictly limited size of his own skull.” – Edsger Dijkstra (Turing Award #7)
  • “Controlling complexity is the essence of computer programming.” – Brian Kernighan (K&R)
  • “So much complexity in software comes from trying to make one thing do two things.” – Ryan Singer (37 Signals)
  • “The cost of adding a feature isn’t just the time it takes to code it. The cost also includes the addition of an obstacle to future expansion… The trick is to pick the features that don’t fight each other.” – John Carmack (Id Software)
  • “I think most programmers spend the first 5 years of their career mastering complexity, and the rest of their lives learning simplicity.” – Buzz Andersen
  • “Nothing is particularly hard if you divide it into small jobs. ” – Henry Ford (BiographyAutobiography)

5. Domain Design: Molding software to fit its domain.

Concept notes:

  • This unique book introduces the importance of discovering a Ubiquitous Language for discussing the domain with customers/users/experts, as well for naming the nouns and verbs in the software representation of the Domain Model. It also places the Domain Model at the center of our system, with the persistence (Repositories) and distribution (Application API) at the edges.
  • If you are used to web application frameworks like Rails or Django, it may seem unusual to have a persistence independent Domain Model. These frameworks can lead you towards using ORM objects as your Domain Model, which couples your persistence details and your Domain Model (at least they led me down this path). Essentially you trade modularity for getting started quickly, which may or may not be profitable based on how large and long lived your system is. Bob Martin gave a great presentation about what an alternative architecture looks like: centered around the Domain Model, with persistence details hidden behind Repository interfaces, and with delivery details (like HTTP) decoupled from the Domain as well. I prefer this alternative architecture, but modularity can increase the number of layers, which can have downsides such as increased learning time and worse performance due to layer translation (but if disk or network is your bottleneck, often this won’t matter).

Further reading:

Related quotes:

    • “Human language appears to be a unique phenomenon, without significant analogue in the animal world.” – Noam Chomsky
    • “I believe the hard part of building software to be the specification, design, and testing of this conceptual construct, not the labor of representing it and testing the fidelity of the representation.” – Fred Brooks (Turing Award #34, Mythical Man Month, No Silver Bullet)
    • “When you actually sit down to write some code, you learn things that you didn’t get from thinking about them in modeling terms… there is a feedback process there that you can only really get at from executing some things and seeing what works. ” – Martin Fowler (Refactoring, Book Series, Agile Manifesto)
    • “Everything should be made as simple as possible, but not simpler.” – Albert Einstein (Nobel Prize, Biography)
    • “There’s a point when you’re done simplifying. Otherwise, things get really complicated.” – Frank Chimero

6. System Design: Holistic views of a system’s structure and qualities.

Concept notes:

      • Books about System Design & Software Architecture generally describe how to think about, work with, and document systems. Then they hone in on the most commonly important system quality attributes (non-functional requirements). There are dozens of quality attributes and their importance varies from system to system.
      • Software Systems Architecture has chapters dedicated to Security, Performance & Scalability, Availability & Resilience, and Evolution.
      • Software Architecture in Practice is a standard textbook (and a potential alternative System Design book), with chapters dedicated to Availability, Interoperability, Modifiability, Performance, Security, Testability, and Usability.
      • ISO 9126 is an international standard for the evaluation of software quality (more description here). Its quality model contains these characteristics and sub-characteristics:
        • Functionality: Suitability, Accuracy, Interoperability, Security
        • Reliability: Maturity, Fault tolerance, Recoverability
        • Usability: Understandability, Learnability, Operability, Attractiveness
        • Efficiency: Time Behavior, Resource Utilization
        • Maintainability: Analyzability, Changeability, Stability, Testability
        • Portability: Adaptability, Installability, Co-Existence, Replaceability

Further reading:

Related quotes:

      • “Most software today is very much like an Egyptian pyramid with millions of bricks piled on top of each other, with no structural integrity, but just done by brute force and thousands of slaves.” – Alan Kay (Turing Award #38, TED Talk, OOP, Smalltalk)
      • “All architecture is design but not all design is architecture. Architecture represents the significant design decisions that shape a system, where significant is measured by cost of change.” – Grady Booch (UML)
      • “Software design must resolve a set of mutually contradictory requirements.” – Kent Beck (TDD, XP, jUnit, Book Series, Agile Manifesto)
      • “The cheapest, fastest, and most reliable components are those that aren’t there.” – Gordon Bell
      • “All computers wait at the same speed.” – Thomas E. Bell
      • “A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work.” – John Gall (The Systems Bible)
      • “Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius – and a lot of courage – to move in the opposite direction.” – Albert Einstein (Nobel Prize, Biography)

7. System Design (Availability): Designing for environmental variation and failure conditions.

Concept notes:

As a system attribute, Availability is discussed as part of the System Design concept. However Availability is important enough to justify its own book on the reading list, especially when a book as excellent and practical as Release It! exists. There are many system quality attributes that contribute to Availability. They are interrelated and it can be difficult to keep the terminology straight (at least it is for me). Here is my attempt to provide definitions and relationships in a way that is consistent with Release It!:

  • Stability: Ability to continue handling requests in the face of component failures or a workload that exceeds capacity. You may not handle all requests, and handling quality may be degraded.
    • Request: An abstract unit of work.
    • Workload: A set or stream of requests.
    • Mixed Workload: A combination of different types of requests.
    • Redundancy: No single point of failure for capabilities or data.
  • Scalability: Ability to add capacity to a system.
    • Capacity: For a workload, the max throughput with acceptable performance.
    • Throughput: Number of requests served in a given time window.
    • Performance: How long a single request takes.
  • Availability: Handling all requests acceptably. Availability often depends on Stability and Scalability (among other things).

Further reading:

Related quotes:

8. System Design (Security): Protecting data & resources.

Concept notes:

As a system attribute, Security is discussed as part of the System Design concept. I was undecided about including an additional book focused on just Security. Security is universally important, but many Security books have too much depth to provide excellent ROI for many software developers. However when I discovered Foundations of Security it made the decision easier. This excellent book has a practical breadth and depth, making it worthwhile for most software developers.

Further reading:

Related quotes:

9. Legacy Code: What happens when a codebase is untested, large, and coupled? How can you fix it?

Concept notes:

I was initially undecided about whether Legacy Code was relevant to most software developers. Some of us are lucky enough to not work with a legacy codebase. I decided to include this excellent book because it provides a view into the implications of technical debt over time. Every software developer benefits from knowing the implications of design decisions and being able to communicate them. This book also provides a toolkit for digging yourself out of trouble. Even if you don’t work with a legacy codebase, there are usually dark corners that need to be managed carefully. For example, if you decide to build on a prototype instead of throwing it away, you may be starting with some amount of Legacy Code.

Related quotes:

  • “To me, legacy code is simply code without tests. I’ve gotten some grief for this definition… I have no problem defining legacy code as code without tests. It is a good working definition, and it points to a solution.” – Michael Feathers (Legacy Code)
  • “The legacy code was so tightly coupled that if you put a chunk of coal between the classes you would get a diamond.” – Jeremy Miller

Further reading:

10. User Experience Design: How do users experience our products & services?

Concept notes:

  • User Experience (UX) is how someone responds to a product or service, including their behaviors, attitudes, and emotions. For users, the UX is the software. A central part of a user’s experience is the User Interface (UI): the collection of mechanisms a person uses to interact with a product or service (i.e. pages & widgets). A good place to start thinking about UX & UI is this essay. A variety of skills and perspectives go into crafting an amazing UX:
  • To be somewhat self-sufficient I think it useful for a software developer to be able to put together “decent” user interfaces. Otherwise you can’t create fully working applications or prototypes without seeking help. Designing Interfaces is a good starting point because it has lot of concrete patterns and examples to get you started quickly.
  • Building on a UI framework like Bootstrap makes it much easier to create decent web interfaces. You benefit from a mature style guide, with reduced novelty as the tradeoff. (Style guides are described in Lean UX.)
  • Designing the UI shouldn’t wait until the last minute. Although a layered architecture can decouple the UI code from Domain code via Application API, in practice the Application’s capabilities must evolve to support an evolving UI. If you follow the agile practice of delivering complete features early & often, then you get feedback about the UI’s needs early & often. (Netflix is an extreme example of UI needs driving the Application API, where a proliferation of UI clients forced them to go beyond a one-size-fits-all API.)
  • Depending on what you work on, an Interaction Design book focusing more on Mobile, Tablet, or TV paradigms may be more directly applicable to your area. (Either way, there is considerable overlap in principles and patterns.)

Further reading:

UX Design is an entire profession, so reading a single patterns book only scratches the surface. There are many excellent and non-redundant books:

Related quotes:

Software Delivery Concepts (#11-16)

11. Lean Systems: Organizing an efficient & adaptive human system.

Concept notes:

An argument could be made that Lean Systems and Agile Team Organization are too similar to warrant separate treatment on this reading list. However, I include Lean Systems separately because it provides the big picture motivation for just-in time adaptive workflows like Agile, including the historical manufacturing context. Lean Systems sets the stage, and Agile Team Organization outlines a way to establish a Lean System for software product delivery.

Further reading:

Related quotes:

12. Agile Team Organization: Organizing incremental & iterative incremental product development.

Concept notes:

  • Agile is a set of methodologies for responding to these and other realities:
    • Like writing an essay, software development is an creative learning process.
    • The most important input to this learning is customer feedback, so you need to deliver working software to customers early & often.
    • Future You is a genius compared to Current You, so defer decisions when possible. Any plans made today will be made with the least information we will ever have.
    • Handoffs don’t work well.
    • Too much work in progress causes problems.
  • I think the Agile Development and Lean Systems communities correctly describe many of the challenges of evolving valuable software with a team. I also think their proposed solutions are generally in the right direction. Not everyone agrees. I wouldn’t say everyone must practice Agile & Lean, but I would say that every professional should know the problems they address and the solutions they propose. You can pick and choose solutions based upon preferences and context. (For example, I am a bit skeptical of Velocity because I am regularly baffled by how difficult it is to predict what issues will arise during development.)
  • Scrum is the most popular flavor of Agile, but you’ll naturally want to choose an alternative book if you’re going to practice a different flavor (i.e. Extreme Programming).
  • I find Scrum to be a list of sensible and low ceremony practices:
    • Sprints: Build software incrementally and iteratively. Deliver working features so you can get customer feedback early and often.
    • User Stories: Write down ideas to work on and prioritize them. Defer figuring out the details (when this is responsible) because you’ll know more later.
    • Scrum Meetings: Regularly talk as a team about what is going on.
    • Sprint Reviews: Regularly show people what you are building to get feedback.
    • Sprint Retrospectives: Regularly discuss how you can work better as a team.
    • Product Owner: Have someone who has the knowledge, authority, and availability to prioritize features.
    • Scrum Master: Have someone focused on process improvement and coordination. This person should ask questions and employ coaching. They should not give orders.

Further reading:

Related quotes:

13. Requirements Design: Cross-functional teams collaboratively designing software.

Concept notes:

    • Although the terms requirements and specification are not perfectly defined, here is a common and useful distinction:
      • Requirements: From the customer and user perspective, what constraints should a product or service satisfy? What should the system do?
      • Specification: From the engineering perspective, how will the requirements be satisfied? How will the system be implemented?
    • Questions for product development teams to answer include: How should requirements be represented? At what level of detail? When should they be written? In Agile projects, User Stories are light-weight goals serving as reminders to have a just-in-time design discussion. After a design discussion occurs, should the conclusions be recorded? Agile’s focus on conversations and working software over documentation suggests that you can often jump into writing tests and coding the feature (after breaking the story into smaller implementation tasks). But what if the design discussion involves complexities such as decision trees, workflows, timing, or other business logic? Then medium-weight representations such as Use Cases (Writing Effective Use Cases) and UML Diagrams (UML Distilled) can help support collaboration and mutual understanding. In contrast, heavy-weight requirements documents are more along the lines of Big Design Up Front.
    • Regarding User Stories vs. Use Cases, here is Alistair Cockburn’s description of when he employs Use Cases on Agile projects. (User Stories Applied also includes a comparison of User Stories and Use Cases.)
    • Ideally requirements are written and prioritized by the customer, or with as much of their input as possible. Writing requirements is a software design activity, so software developers can help guide the process by explaining:
      • How to structure stories.
      • When a story is too large for an iteration (or too small).
      • How to split up stories by feature rather than layer (thus delivering working features for each story).
      • How to avoid specifying user interface details, because requirements should only constrain outcomes (not how outcomes are achieved).

Further reading:

Related quotes:

      • “If we’d asked the customers what they wanted, they would have said ‘faster horses’.” – Henry Ford (Biography, Autobiography)
      • “Computers are good at following instructions, but not at reading your mind.” – Donald Knuth (Turing Award #9, TAOCP)
      • “Know thy user, and you are not thy user.” – Arnie Lund
      • “I love software, because if you can imagine something, you can build it.” – Ray Ozzie (Lotus Notes, Microsoft CTO)

14. Testing Products & Services: Do our products & services provide what our customers need?

Concept notes:

Testing products & services requires a diverse skill set. I believe software developers should strive to do as much of this as possible themselves. Books like Agile Testing and How Google Tests Software point the way. However these books also make it clear that several categories of high value testing and clarification are most effectively pursued by dedicated testing experts. Agile Testing is structured around Brian Marick’s testing quadrants:

      1. Technology-Facing, Supporting the Team: Unit Tests, Component Tests
      2. Business-Facing, Supporting the Team: Functional Tests, Examples, Story Tests, Prototypes, Simulations
      3. Business-Facing, Critiquing the Product: Exploratory Testing, Scenarios, Usability Testing, User Acceptance Testing (UAT), Alpha/Beta
      4. Technology-Facing, Critiquing the Product: Performance & Load Testing, Security Testing, “ility” Testing

Further reading:

Related quotes:

15. Continuous Delivery: Automated pipeline for integration, testing, & release.

Concept notes:

Continuous Delivery is a broad concept that relates to Continuous IntegrationAutomated Testing, Configuration Management, Automated Deployment, Release Management, DevOps, and much more. Combining these practices into a (fully or mostly) automated delivery pipeline is essential to establishing a lean/agile/just-in-time/adaptive software delivery workflow. The actual release schedule is a business decision, but we should be technically able to release after every sprint (if not every day). Here is a sample set of Delivery/DevOps tools for a Java web application:

Further reading:

Related quotes:

      • “Release early. Release often.” – Eric Raymond (Cathedral & Bazaar, TAOUP)
      • “By far the dominant reason for not releasing sooner was a reluctance to trade the dream of success for the reality of feedback.” – Kent Beck (TDD, XP, jUnit, Book Series, Agile Manifesto)
      • “Stop the line, so the line never stops.” – Toyota Production System
      • “Amateurs work until they get it right. Professionals work until they can’t get it wrong.” – Unknown
      • “Besides black art, there is only automation and mechanization.” – Federico Garcia Lorca
      • “Usage is like oxygen for ideas. You can never fully anticipate how an audience is going to react to something you’ve created until it’s out there. That means every moment you’re working on something without it being in the public it’s actually dying, deprived of the oxygen of the real world.” – Matt Mullenweg (WordPress)

16. Customer Development: Creating customer value.

Concept notes:

      • Lean Startup ties together several of this reading list’s concepts: Lean Systems, Agile Team Organization, Continuous Delivery, and Customer Development.
      • Software is valuable if it is used. A software developer’s goal is to create valuable software. The idea of Customer Development is to approach value creation as a science, not as a black art. The strategy is to iteratively apply the scientific method to:
        • Problem/Solution Discovery: Discover a problem there is value in solving, and evolve a solution to the problem.
        • =
        • Market/Product Discovery: Discover a market there is value in addressing, and evolve a product that fits the market.
      • They Made America distinguishes between Inventors and Innovators. Inventors create inventions (Tesla, Wozniak). Innovators bring inventions to the masses (Ford, Gates). Some inspiring people succeed at both (Edison, Jobs, Musk).
      • Your era matters: 14 of the 75 richest people ever were born in 1830’s USA as a result of industrialization. These individuals were part of a larger group of people who successfully responded to the profound technological changes at that time. Change creates opportunity. Today is also a time of profound technological change. Much of this change is centered around software. If you’ve read this far, you’re probably a software developer like me. I feel extremely fortunate that individuals with our particular skill set, at this particular time in history, are able to have such an unprecedented impact on people’s lives and the world in general.
      • Software is changing many areas: phones, TVs, cars, exercise, communication, retail, homes, books, news, healthcare, drugs, education, dating, networking, movies, golfgovernment, cities, printing, politics, and pretty much everything else. What do you want to improve?

Further reading:

Related quotes:

One last note: Learning a craft requires a balance between studying and doing.

      • “An investment in knowledge always pays the best interest.” – Benjamin Franklin (Biography, Autobiography)
      • “Reading furnishes the mind only with materials of knowledge; it is thinking that makes what we read ours.” – John Locke
      • “One glance at a book and you hear the voice of another person, perhaps someone dead for 1,000 years. To read is to voyage through time.” – Carl Sagan (Pulitzer Prize, Cosmos, SETI)
      • “Most papers in computer science describe how their author learned what someone else already knew.” – Peter Landin
      • “Mathematicians stand on each others’ shoulders and computer scientists stand on each others’ toes.” – Richard Hamming (Turing Award #3)
      • “Forgive him, for he believes that the customs of his tribe are the laws of nature!” – George Bernard Shaw
      • “If people knew how hard I worked to get my mastery, it wouldn’t seem so wonderful at all.” – Michelangelo Buonarroti (BiographyMedici Documentary)
      • “I have been impressed with the urgency of doing. Knowing is not enough; we must apply.” – Leonardo da Vinci (Biography, Notebooks, Medici Documentary)
      • “I hear and I forget. I see and I remember. I do and I understand.” – Confucius
      • “All our knowledge begins with the senses, proceeds then to the understanding, and ends with reason.” – Immanuel Kant
      • “Be self aware, rather than a repetitious robot.” – Bruce Lee

Other Software Development Reading Lists

Be sure to note the dates on some of these.

42 thoughts on “A Software Developer’s Reading List

  1. Colin Quirke

    Fantastic List. I have read about half, and many on your further reading lists. I would add the category “Professionalism” and Bob Martin’s, Clean Coder. Changed my whole approach to development and got me to actually start doing some of the stuff I knew I should (TDD, paring, etc.)

    Reply
  2. JoesTechLife

    This is a great list. I am just getting started in software development and I need something like this list to get me through. Honestly I am very impressed with the amount of books and how you have everything laid out in this. From theories to what you should be getting from these books.

    Reply
  3. Magnus Hedemark

    Reblogged this on Opus Magnus and commented:
    Check out this great reading list for Software Developers. If you’re thinking of getting into this line of work, or you’re in it but want to bring up your game, this instant library should be helpful in building good work habits out of best practices.

    Reply
  4. Steve Wedig Post author

    Thanks Magnus! I’m coming from the other direction, starting from software design and being pulled towards DevOps by Continuous Delivery and the desire to know how the whole system works.

    Reply
  5. Seb Rose (@sebrose)

    Great list.

    Personally, I’d make the following substitutions:
    Object Design -> Object Thinking – David West (Microsoft Press – but not a M$ book at all)
    S/W System Architecture -> Software Architecture for Developers – Simon Brown (LeanPub)
    Essential Scrum -> Art of Agile – James Shore (O’Reilly)
    User Stories Applied -> Bridging The Communications Gap – Gojko Adzic (Neuri Limited)

    Finally, any reading list that doesn’t has space on it for Waltzing With Bears – DeMarco & Lister needs to be made on book bigger ;)

    Reply
  6. Steve Wedig Post author

    Thanks for the suggestions Seb! Those sound like the kind of books I was looking for. I’ve added them to the Further Reading. When I find time I think I’ll be revising this list to integrate a lot of feedback, so I’ll be sure to review those books.

    It is difficult to pick a single book for each concept, and there is no “right” answer.

    My thinking in choosing S/W System Architecture was that I felt this was one area that warrants an actual textbook level of coverage, and I liked their narrative, their organization, and the Amazon reviews confirmed my opinion.

    In choosing Essential Scrum and User Stories Applied I wanted to suggest super practical books because that will be useful to the widest audience. I left the theory of the Agile movement and the expansive field of Requirements Communication as further reading. It seems that your recommended books would provide more coverage of these areas, which seems to make sense for some readers. (Whether it is 20% or 80% of readers I have no idea.)

    Reply
  7. Steve Wedig Post author

    I agree Josué! I have the PPP book listed under Further Reading in the Component Design concept, along with a link to Uncle Bob’s SOLID principles. Component Design is definitely an area that warrants reading several books.

    Reply
  8. David Burstin

    This list is fantastic. I would add Practical Object-Oriented Design in Ruby by Sandi Metz. Ruby is the language she uses for I am not a Ruby developer but this book is an excellent resource on OO design in whatever language you use. For me it is right up there with GOOS as required reading for anyone interested in creating highly maintainable, adaptable and reuasble object-based software.

    Reply
  9. Steve Wedig Post author

    Thanks for the suggestion David! Practical OO Design in Ruby has the most 5 star Amazon reviews that I’ve ever seen. I’ll definitely be reviewing it for the next version of this reading list.

    Reply
  10. Steve

    It’s a good basic list (especially the Fowler and Nygard recs)

    fwiw (and respectfully) here’s what I’d change:

    – Drop all of the process books, read Peopleware. Beyond that, have your team maintain a constantly-reviewed list of 10 priorities, work on no more than top 3 or 4 at a time (anything more elaborate than this, like tracking velocity, etc, is just a distraction – teams will make metrics or arbitrary deadlines “work”, one way or another, but that’s quite apart from the question of whether a product is advancing or improving). Put a bug tracker in place and be rigorous about using it. Get together occasionally and talk about what’s going well and what isn’t. Work from the needs of your org and product “in” to come up with a reasonable process – fashionable methodologies should perhaps inform it, but they should not be used as a starting point.
    – DDD is good overall but it’s pretty dense and long – outside of the Ubiquitous Language part(s), I would do no more than skim it.
    – Refactoring is a pretty quick read, because it’s mainly valuable for the small number of prose parts, which are good basic advice about how to develop quality software. The dictionary of refactorings is good reference material to have around, but just skim it.
    – GOOSGBT is a good book, but I would instead have people go through any basic language-specific unit-testing tutorial, then read through relevant parts of Fowler’s bliki (e.g. http://martinfowler.com/tags/testing.html)

    > I’m not sure what book to use. Subjects include relational vs. key-value, normalization vs. performance, transactions, big data, sharding, consistency, distribution, UUIDs, backup+recovery, scaling, schema evolution, etc.

    CJ Date’s Database in Depth is good:
    http://www.amazon.com/Database-Depth-Relational-Theory-Practitioners/dp/0596100124/

    > Software Development, not Computer Science: There actually isn’t much overlap between a professional software development curriculum and a traditional computer science curriculum. A computer science degree often includes learning programming plus subjects such as Automata Theory, Algorithms, Programming Language Theory, Operating Systems, Networking, Cryptography, Databases, Artificial Intelligence, and Hardware Design, etc.

    I have a real beef with this. “Algorithms, Programming Language Theory, Operating Systems, Networking, Cryptography, Databases” – not getting into this stuff limits you pretty severely in terms of what you’re capable of creating. It also means you’re limited in quickly evaluating in your head (vs by much more slowly iterating via code) what sorts of approaches are appropriate given a technical challenge in front of you.

    This critique could be expanded to include Lean Startup mentality. You can make a product by teaching yourself to iterate-iterate-iterate really fast (i.e. hill-climbing). Certainly this is extremely important, but it’s only really powerful if done with a good foundation in place such that you can quickly and confidently design (an architecture. a business strategy.). For tech, that means understanding in depth, “what can modern computers+networks do for me? what are the limits?” and in a business context that means “how does this business domain work?”. If your team is attempting to use fast iteration to replace depth on either of these fronts, rather than as a force multiplier, you risk spinning your wheels.

    Reply
    1. Steve Wedig Post author

      Thanks for your thoughtful observations Steve, I really appreciate the feedback.

      I agree that not everyone needs to read every word of the Refactoring catalog and the later DDD chapters. (I had these kind of areas in mind when I say some books have parts you can safely skip.) I like the GOOS book because it shows the relationship between TDD and evolutionary design. I also agree that with all the discussion of iteration and fail fast, there isn’t enough mentioning that it is far better to have a high quality hypothesis than to stumble around. A depth of experience and domain knowledge helps hypothesis formation tremendously. I’ve read Date’s manifesto but haven’t read Database in Depth, so I’ll take a look at it.

      Regarding the inclusion of Agile processes on the list, and regarding the amount of overlap between computer science and software development curricula, I think we do have a difference of opinion. As a result, I have expanded the explanation of my point of view, which I include below for convenience…

      Regarding Agile & Lean:
      I think the Agile Development and Lean Systems communities correctly describe many of the challenges of evolving valuable software with a team. I also think their proposed solutions are generally in the right direction, and a significant improvement over 15-20 years ago. Not everyone agrees. I wouldn’t say everyone must practice Agile & Lean, but I would say that every professional should know the problems they address and the solutions they propose. You can pick and choose solutions based upon preferences and context. (For example, I am a bit skeptical of Velocity because I am regularly baffled by how difficult it is to predict what issues will arise during development.)

      Regarding CS & SD:
      Software Development, not Computer Science: (The following observations are not a consensus. They are my opinions based on my experience which includes being a computer science teaching assistant for C++, assembly, logic design, algorithms, databases, and artificial intelligence, followed by 7 years of professional software development.) There is limited overlap between a professional software development (SD) curriculum and a traditional computer science (CS) curriculum. A computer science degree often includes learning programming plus courses including automata theory, algorithms, programming language theory, operating systems, networking, cryptography, databases, artificial intelligence, hardware design, etc. A functional understanding of algorithms, data structures, and complexity (big O) is important for programming. A CS database course provides a theoretical foundation for the broader SD challenge of data management in practice. Other than algorithms and databases, I’ve found many CS subjects to be optional (but occasionally helpful) for many kinds of development. In some areas a background in UX design or domain knowledge might actually be more helpful than CS.

      Reply
      1. Steve

        > their proposed solutions are generally in the right direction, and a significant improvement over 15-20 years ago. Not everyone agrees.

        I don’t disagree that waterfall, or whatever you’re implicitly drawing a contrast to, is often a worse choice. I do disagree with the frame that methodologies drive outcomes – i.e. if you want a better outcome, you choose an (objectively) better methodology. Methodologies, to me, are more a reflection of the local team+company culture – a trailing indicator.

        A post from today nails this distinction:
        http://typicalprogrammer.com/why-dont-software-development-methodologies-work/

        This is where my recommendation for PeopleCode (and disregarding of most Agile planning material) comes from: that book is an attempt at cracking the problem of what makes for a jelled team. A jelled team can pick probably any methodology they want and kick a non-jelled-but-Agile team’s butt all over the place.

        > A functional understanding of algorithms, data structures, and complexity (big O) is important for programming. A CS database course provides a theoretical foundation for the broader SD challenge of data management in practice. Other than algorithms and databases, I’ve found many CS subjects to be optional (but occasionally helpful) for many kinds of development.

        Having had that background I’m pretty sure that you can visualize the important aspects of what goes on in a database – the value of indexes, what’s going on in a hash join, why it’s important for indexes to live in ram vs on spinny disk, the cost of a sort, the effects of locking etc – without much effort. I theorize that it’s much more efficient to understand and reason about this stuff having studied the CS fundamentals. Technical decisions that take two months to fully back out of may go one way or the other based on having developed these sorts of instincts.

        Finally, before I forget, I would add one more must-read, since messaging (reliable and otherwise) is at the heart of building a modern system in a networked environment, where failures of various sorts are the norm:

        Gregor Hophe’s “Enterprise Integration Patterns”
        http://www.amazon.com/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683

        Reply
        1. Steve Wedig Post author

          In case I have implied it, I am not arguing against Peopleware as a classic book. I had originally thought it was out of scope of this reading list, but I will be re-evaluating that decision.

          I do believe everyone should be exposed to the concept of Lean Systems, as well as the problems that Agile Team Organization hopes to address, and the practices Agile suggests as solutions. As you point out, these practices (methodologies) are not at all a silver bullet. Instead of magic that will fix a broken team, I find Scrum to just be a list of sensible and low ceremony practices:
          – Sprint: Build software iteratively and incrementally. Deliver working features so you can get customer feedback early and often.
          – Stories: Write down ideas to work on and prioritize them. Defer figuring out the details (when this is responsible) because you’ll know more later.
          – Scrum Meeting: Regularly talk as a team about what is going on.
          – Sprint Review: Regularly show people what you are building to get feedback.
          – Sprint Retrospective: Regularly discuss how you can work better as a team.
          – Product Owner: Have someone who has the knowledge and authority to prioritize features.
          – Scrum Master: Reify team improvement as a person responsible for coaching and coordination, but not giving orders.

          Like you say, it is difficult for me to imagine not having a CS background.

          I agree that EIP is great and that messaging is fundamentally important. I list EIP under System Design’s further reading section. Like PEAA, I think it is a great followup to Software Systems Architecture and Release It.

          Edit: Got rid of the 15-20 years part, that wasn’t clear. Also I’m planning on adding a Management concept with Peopleware as the book.

          Reply
  11. Sendhil Kumar R

    Thank you very much for the list Steve.
    I do agree with Steve (the guest commenter) on peopleware.
    I am with you on Software Development, not Computer Science.
    Here is my personal opinion.
    I would place Patterns of Enterprise Application Architecture in the main list.
    May be under system design or may be you need a separate patterns category.
    Object Design and DDD (especially the later parts) are really dry.
    But I do agree that they are required reading.
    Hopefully someone rewrites them in an more interesting way.

    I do not agree with you on your classification of SICP.
    SICP is about building abstractions, may be you should consider it along with the MIT’s Open Courseware lectures by Abelson and Sussman. I can forgo all of this list just for that one series of lectures.

    Regards,
    Sendhil

    Reply
  12. Steve Wedig Post author

    Thanks for the feedback Sendhil!

    There is no doubt that Peopleware is a classic book. My original thinking was that Peopleware was outside of this list’s scope. I will have to think more about that decision.

    PEAA is a great book that I would recommend to anyone (along with many of the books in Martin Fowler’s series). Patterns are a great way to gain from existing wisdom in an area. However based on the goals of this reading list, I would be hesitant to include it in the main list. Based upon your feedback I have expanded my explanation of this reading list’s goals:
    “I believe these 16 books are a great start for any professional software developer (after learning programming). It is certainly a much more direct path than I took. By no means are these the only excellent books or the only books you should read. This list is simply the most effective and efficient overview I know how to recommend. The “Further Reading” sections contain many important and classic books.”

    I agree that Object Design can be dry. Based on David Burstin’s recommendation above, I just got Practical Object-Oriented Design in Ruby in the mail today, and it is very engaging. I haven’t reviewed it for content yet, but the writing is probably more engaging than any book on this list. The stellar Amazon ratings reflect this. An interesting note is that Object Design’s author was a reviewer of this 2012 book.

    I agree that the DDD book can also be dry. I don’t know of a more engaging presentation of this important way of thinking about the domain. I was pretty enthralled reading it because of how much it affected my thinking.

    SICP is an amazing programming book. It really impacted how I understand programming, particularly abstraction. Every programmer should read it after they get some experience. I think I am going to be adding a “professional programming” concept in order to accommodate Code Complete, so I will link to the MIT Open Courseware lectures under Further Reading. Thanks for the tip. However I do want to keep programming outside the scope of this list. Otherwise I’ll have to double the size of the list and it would lose focus and clarity.

    Reply
    1. Sendhil

      Thanks for the response Steve.
      Glad that you are considering a professional programming concept / category.
      Thanks for the suggestion of Practical Object-Oriented Design in Ruby, I haven’t read it.
      I will add it to my wish list.

      Regards,
      Sendhil

      Reply
  13. Pingback: A biblioteca do Desenvolvedor de Software dos dias de hoje | Vinicius Cardoso Garcia, D.Sc.

  14. Pingback: Weekly Reading List | Robert Cina Online

  15. Pingback: Reading List : Development List | KGet

  16. Pingback: My Summer of Code – Part One: Full Stack Coder | James M.G Coombs

  17. Pingback: Kool Architectural Resources and Sample Apps(mostly in .NET) | Insight's Delight

  18. samuel

    Just 16 books but very good choices, technology agnostic with a very deep explanation of each one. I already own 14 of them and you give me interest to the others: lean startup and software systems architecture.

    Reply
    1. Steve Wedig Post author

      If you own 14 of my favorite 16 then I bet you own a lot of books. I’m managing an Amazon addiction myself :) The best one I’ve read recently is Seven Concurrency Models in Seven Weeks.

      Reply
      1. samuel

        Ahhhhhh, you’re right about my own books collection ;) And because of you, I have another book to read. I just read the first chapter of Seven Concurrency Models in Seven weeks and it’s delicious! We do the best job in the world :D

        Reply
  19. Pingback: หนังสือที่ทีมพัฒนา software ควรที่จะต้องอ่านไว้บ้าง

  20. Pingback: A Software Developer’s Reading List | Nicholas White

  21. Pingback: A Software Developer’s Reading List | Nicholas White | Programming Potato

  22. Kazem

    This is a great list for software engineering books – Thanks for sharing Steve.

    At A.I. Optify we have taken a data science approach to mine the web and rank the top 40 Software Engineering books.

    Our data science team has scraped various signals (e.g. online reviews & ratings, topics covered in the book, author popularity, price etc.) from open web for more than 300’s of Software Engineering books.

    We have combined all signals to compute a Fit Score for each book and publish the list of top Software Engineering books.

    You can view the list of top 40 Software Engineering books here:

    http://aioptify.com/top-software-books.php?utm_source=contentpromotion&utm_medium=cpm&utm_campaign=topsoftwarebooks

    Reply
  23. Yogev Sitton

    One thing I’ve always wanted to do is read more software development books, but there‘s an endless list of “Must Read Books For Developers”. The list of lists of “Must Read Books For Developers” isn’t small either…

    I decided to do some digging and come up with as many lists as I could (18 lists were found) and make one “ultimate” list by ranking these books by number of appearances.

    This is one of the lists I used (it is also listed as a source) – thanks for the good work :)

    View story at Medium.com

    Reply
  24. Pingback: What are the best websites a programmer should visit? – Quora Bites

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s