by John Turner
Posted on June 29, 2010
If you are a software developer, The Pragmatic Programmer is not just a book but an arm around your shoulder, the mentor that you never had. It has rightly earned its place on the bookshelf of every self respecting software developer in the land. First published in 1999, it is as relevant today as ever.
Ron Jefferies said about this book ‘As with any such book, much of the advice is something you already know. Much of it is also something you have forgotten to focus on lately.’. You may or may not learn anything new, but this book will remind you what is important.
Chapter Summary
Chapter 1 - A Pragmatic Philosophy
‘Software Entropy’ is compared to the ‘Broken Window Theory’ and some causes and consequences are discussed. This is a very useful analogy and comparable to technical debt as used by some agile methodologies.
The knowledge portfolio is a very useful concept and it never ceases to amaze me how little software ‘professionals’ invest in their development. Join a ‘big 4’ accountancy firm and you will be mentored through an intensive training programme; medical and legal professionals are required to earn ‘continued professional development’ (CPD) points and yet some software developers aspire to be considered ‘professional’ without ‘Investing in their Knowledge Portfolio’. It’s not all one way though; the knowledge portfolio needs to be valued more by those employing software ‘professionals’.
One of the sentences that stood out when discussing communication was the following: ‘This isn’t communicating: it’s just talking, and it’s annoying’. How true this is and it’s the role of a strong meeting facilitator (Scrum master etc.) to ensure that participants are communicating and not just talking. The same goes for email groups and so many things besides.
Chapter 2 - A Pragmatic Approach
‘The Evils of Duplication’ highlights the areas were duplication can (and does) occur, the consequences and how to best avoid duplication. This includes requirements and design documentation as well as code.
The recommendation to have in built ‘Reversibility’ not only reinforces the OO principles of encapsulation and programming to interfaces but goes further by suggesting that these be applied at an architectural level. Of course this process has a limit and some decisions will always be difficult to reverse.
‘Tracer Bullets’ are described as end-to-end implementations of a subset of functionality that is built upon to deliver the complete solution. I guess this is similar to what is often referred to as ‘spikes’ except that Tracer Bullets are incorporated in the complete solution.
The use and abuse of prototypes are discussed along with some decisions to make when considering prototyping. The choice of using ‘Tracer Bullets’ as opposed to prototypes is also covered.
Tips and techniques for estimating are explored along with some insightful thoughts on how people interpret estimates. For example, an estimate of 16 weeks or 4 months is the same (approximately) in terms of duration but the latter suggests a greater degree of uncertainty.
Chapter 3 - The Basic Tools
Stepping out of the IDE used to be something that every developer did frequently. Now it is less common and we are reminded of the power and flexibility of shell commands.
Source control systems have evolved significantly over the past few years and we are reminded why we use source control and where its value lies. Useful stuff if you are trying to make a case to move away from your current source control system. While migrating source can be challenging, I’m often surprised at the inertia in this area when the benefits are substantial.
In football, commentators often talk about ‘playing the percentages’ and this concept is used to discuss debugging and root cause analysis. Look in the most likely places first (i.e. your own code) and you will find bugs faster. The tendency to point somewhere else must be overcome. Other useful practices such as feeding bugs back in to regression testing are discussed.
Code generation is discussed and importantly how it violates the DRY principle to check in code generated by active code generators. This is something I see often and it is normally accompanied by some justification. With the flexibility and power of today’s build tools, I feel there is no justification for checking in actively generated code.
Chapter 4 - Pragmatic Paranoia
Design by contract (DBC) is introduced in the context of method contracts. Of course, these days when DBC is discussed we are usually referring to web services but more fundamental is the contract of our methods. Assertions are a good tool for enforcing method contracts and some of the subtleties of using assertions are discussed.
The other sections on exceptions and resource management are probably well known to most nowadays as there is a greater awareness of these subjects.
Chapter 5 - Bend, or Break
Coupling is explained and a description of using the Law of Demeter to reduce coupling for functions is given. It was interesting to have this laid out in black and white. The sort of knowledge one should absorb and apply without thinking (although it’s useful to work through the thought process).
The benefits of meta-data driven programming are extolled although again I would say that programmers are more aware of this type of programming and the trade-offs that at the time the book was written.
Temporal coupling (as pointed out by the author) is often forgotten, or not given enough focus (even in today’s world of multi-threaded, distributed systems) during system design. A solid understanding of the temporal coupling within a system will make opportunities for improved concurrency more visible.
The Model-View-Controller pattern, Observer pattern and Publish-Subscribe paradigm are discussed in the context of reduced coupling. Additional reading is necessary for the reader to fully grasp the concepts being presented.
Blackboards or shared-spaces are discussed along with their potential to reduce coupling. I recently took an agent oriented programming course so this material was very familiar.
Chapter 6 - While You Are Coding
I found the first paragraph in this chapter very striking as I have had many experiences that reinforce the point. This paragraph states:
‘Conventional wisdom says that once a project is in the coding phase, the work is mostly mechanical, transcribing the design into executable statements. We think this attitude is the single biggest reason that many programs are ugly, inefficient, poorly structured, unmaintainable, and just plain wrong.’
The emergence of Agile methodologies has gone some way to increase the awareness of this point by pushing design closer to implementation but this problem has not gone away.
An overview of how to estimate algorithm speed is provided and some guidance is provided to apply these techniques. As is stated, this is not something that most developers have to be overly concerned about but all should have an appreciation and awareness of the effect different algorithms can have on performance.
Refactoring and unit testing are then discussed. Developers are a lot more aware of these subjects than when the book was originally written but nevertheless the sections provide a useful refresher.
A section on wizards or ‘Evil Wizards’ describes the potential hazards of using wizards and adopting code that you may have little understanding of.
Chapter 7 - Before The Project
Pragmatic approaches to determining and documenting requirements are discussed along with some common mistakes.
‘Solving Impossible Puzzles’ encourages use to take a step back, look at the puzzle we are trying to solve, try to solve it in other ways or perhaps it is not a problem we need to solve after all.
‘Circles and Arrows’ reminds us to take what is useful from formal methods and leave behind those things that are not.
Chapter 8 - Pragmatic Projects
Previous techniques are revisited with a focus on how their characteristics change when applied to a team of programmers.
Automation is then covered in some detail including code/documentation generation as well as automated build, test, coverage etc.
‘Ruthless Testing’ encourages programmers to think about the value of testing, add tests that are valuable and test the tests. When a bug slips through the net test suits should be enhanced to reduce the chance of future occurrences.
‘It’s all Writing’ outlines the importance of writing documentation in a way that adheres to the DRY principle and that follows the same pragmatic approach taken when writing code.
Thoughts
Each section describes a pragmatic practice that one might adopt in an attempt to improve working practice and performance. In the foreword by Ward Cunningham, Ward compares the presentation of the material to that of pattern languages. This is because each section is described concisely with ‘Related Sections’ and ‘Challenges’. This worked out great for me because I want bite sized nuggets of information to read on my daily commute. I am never forced to put the book down in the middle of a section as they are short enough to read quickly and independent enough that they can be read in any order.
As with its follow up ‘Pragmatic Thinking & Learning’, ‘The Pragmatic Programmer’ is littered with relevant quotes. Again, I have highlighted some of my favourites below:
Benjamin Franklin, ‘An investment in knowledge always pays the best interest.’
Mae West, ‘I believe it is better to be looked over than it is to be overlooked.’
Emil-Auguste Chartier, ‘Nothing is more dangerous than an idea if it’s the only one you have.’
Woody Allen, ‘When everybody actually is out to get you, paranoia is just good thinking.’
Ralph Waldo Emerson, ‘Nothing astonishes men so much as common sense and plain dealing.’
If you want to read a book that just makes sense then this is the book you have been looking for. You will find yourself repeating ‘how true’ over and over again until the point when you ask ‘This stuff is so obvious. Why have I not thought of this before and why are we not acting upon it.’ Well here is your chance to redeem yourself; pick up a copy, read it, then apply it.