As an experienced leader of software development teams, I’m often asked what I would recommend as reading materials for developers. With that in mind, I’ve decided to collate by hand a list of great books that I believe every developer should read, regardless of their inclinations towards front-end, back-end, or language.
Take pride in your craft and refine your overall development skills by learning from the masters:
This is a must-buy for any developer. Originally published in 1999, it has become the standard text for learning to be a better developer. Introducing what are now well known concepts such as DRY (Don’t Repeat Yourself) and Orthogonal Systems, this book covers many pertinent development subjects such as fighting software entropy or rot; writing flexible, dynamic and adaptable code; avoiding programming by coincidence; bullet-proofing code with contracts, assertions and exceptions; capturing real requirements; and taking responsibility for your code through strong design, teamwork, and testing.
Another great book from the 90s, Code Complete lays out a better process for development. McConnell really laid out the concepts that would move development away from upfront waterfall-type development cycles and lead teams to a more agile model (this before the agile manifesto was even written). This book also does a great job of introducing the techniques required for effective software construction with an emphasis on this over documentation and planning. What started here later became TDD and Agile.
As Erich Gamma states in the foreword, “this book is crammed with sensible advice for software development”. “Uncle” Bob Martin is, without a doubt, one of the leading voices in effective software development, and this book lays out the important processes, design patterns, and principles that are the foundation for building and working in high quality agile development teams. Second only to “Clean Code” (listed below in “Code Quality”) within my recommendations of Uncle Bob’s works.
“Feature complete” is not the same as “production ready.” In this book, Michael Nygard calls on his extensive experience living with systems in production having often been the one to get woken up at three in the morning when some supposedly 24x7 system goes down. With a combination of case studies and practical advice, this book will really help you understand how to overcome the final hurdle of getting your code into the real world.
Domain modeling is central in software design. Through domain models, software developers are able to express rich functionality and translate it into a software implementation that truly serves the needs of the user. This book offers a systematic approach to domain-driven design, presenting an extensive set of design best practices, experience-based techniques, and fundamental principles that will improve your ability to develop software projects in complex domains.
Martin Fowler is a leading voice in software and application design. This book of pragmatic patterns is an good resource for any aspiring architect or software designer. The content is now a little out of date–particularly in reference to certain technologies–but the overall methods, approaches, and patterns are still pertinent.
These books will teach you to take pride in your work and generate high quality code. Consider this your ammunition for confident participation in code reviews.
If I had to recommend just one book for any developer to read, it would be this one. Uncle Bob really sets out to right a lot of wrongs here and gives very clear and concise advice on how to write high quality code that will be appreciated by your teammates and future you. Outlining practices and processes, and using case studies to further enforce the ideas, Clean Code is most definitely a must-buy. Contents include how to tell the difference between good and bad code; how to write good code and how to transform bad code into good code; how to create good names, good functions, good objects, and good classes; how to format code for maximum readability; how to implement complete error handling without obscuring code logic; how to unit test and practice test-driven development.
This book is a fantastic collection of patterns for writing simple, clean, clear code in a more organised way. Good code doesn’t just happen and this book will teach you how to ensure you are always producing quality. It covers subjects such as the value of communicating through code and the philosophy behind patterns; how and when to create classes, and how classes encode logic; best practices for storing and retrieving state; writing, naming, and decomposing methods; choosing and using collections; and implementation pattern variations for use in building frameworks.
TDD is a paradigm that is widely adopted by development teams. Although over 10 years old, this book is the definitive guide on the whys and hows of Test-Driven Development. In it, Beck explains why TDD eliminates tentative traits, teaches programmers to communicate, and how it encourages team members to seek out criticism. Code should be continually tested and refactored and this book will tell you why that’s a good idea.
Following on from TDD above, this seminal work explains the true art of refactoring. Fowler and Beck use their tremendous experience of development and the software industry to explain how to rework a bad software design to make it good, without breaking the system itself. This book offers a thorough discussion of the principles of refactoring, where to spot opportunities for refactoring, and how to set up the required tests. Despite using Java as the example language, the principles in this book can be translated to any OO environment.
Every developer dreads dealing with legacy code. This book seeks to explain how to avoid the temptation to rewrite from scratch and also outlines common issues–and the techniques to overcome them–that arise when dealing with legacy code. Really, this book is another dive into testing and how sometimes it’s a good idea to retrofit tests to systems you haven’t written yourself to allow for efficient refactoring. If you’ve got the two books above, you should follow-up with this one.
Behaviour Driven Development, or BDD, is an alternative approach to TDD where tests are written more as user-stories. This Ruby-specific book is a really good introduction to the technique and how you can use it to your advantage in an Agile environment. Having tests that can be easily written by a non-technical contributor–or even your customers/users–opens up the possibility for improved communication and requirements gathering.
This is a classic work that should be included in any developer or programmer’s bookshelf. It’s easy to read, it’s still interesting, and it raises many points that are worthy of further thought. Despite being out-of-date in relation to languages and techniques, this book cannot be ignored.
“A literate programmer is an essayist who writes programs for humans to understand, instead of primarily writing instructions for machines to follow.” The underlying message of this book changed the way development was handled, moving from ensuring the optimum performance for machine to the optimum readability and maintainability for the teams supporting the software. Again, this is a must-have book for any development bookshelf.
Learning how to work with objects effectively is important when working with all systems, regardless of complexity. These books will help you think in an advanced object-oriented way.
This book is also known as the “Gang of Four (GoF) book” due to its four authors. It is very much required reading for anyone working in an object-oriented environment and lays out a fundamental set of design patterns that developers are likely to be using regularly. Treat this as a bible for good object-oriented design and give it pride of place on your bookshelf.
This book is a fantastic companion to the gang of four book because it is full of object design techniques. Not just an explanation of common patterns, it provides the reader with the tools needed to think through their object design in depth. Topics covered are: Strategies for selecting and rejecting candidate objects in an emerging design model; object role stereotypes and how to identify objects' behaviors; how to characterise objects using role stereotypes; allocating responsibilities to appropriate objects; developing a collaboration model; strategies for designing application control centers; documenting and describing a design, focusing on use cases, design conversations, and annotations; strategies for enhancing reliability, including handling exceptions and recovering from errors; how to characterize software variations and design to support them for greater flexibility; and how to categorize and treat various kinds of design problems.
It’s good to understand more than just one language to ensure you do not become blind to new data-structures or techniques that could help you in the future. Here are a bunch of books that I’ve found lead me down a path of enlightenment.
Despite the misleading title, this is not one of those “learn x in x time” type books. Rather, this is an interesting delve into what makes each of the seven specific languages (Clojure, Haskell, Io, Prolog, Scala, Erlang, and Ruby) different. Learning many programming languages is a good technique in finding new and interesting ways of solving a problem, and translating techniques from one to another can be the difference between a good and great developer. This book doesn’t try to teach you how to build a “Hello World” in each language, but it does teach you why prolog is a great language for creating a Sudoku solver, and why Ruby’s mixins and meta-programming make it extremely powerful for specific problems.
Learning the effective use of databases is imperative for any good software developer. Don’t just make this the realm of the DBA; get your hands dirty and dive into that DB.
I’ve really lost count of the good things I’ve learnt from this book. Despite being written in a time that Unix was a more prevelant operating system, its contents are still relevant to any developer working with Linux or Mac OS X since those systems have Unix as their base.
Learning how to interact with the web in a way that doesn’t alienate your users is deeply important when creating quality software.