I recently read a terrific blog post titled “Lessons Learned in Software Development” by Henrik Warne (http://henrikwarne.com/2015/04/16/lessons-learned-in-software-development/). In it, he lists 22 general lessons he has learned over the years, many of which seem obvious in hindsight. As a developer, there are more than a few in there that have saved me countless hours, and there are others that I hope will save me even more moving forward. I encourage you to hop over to his site and read the post in its entirety before going any further! The discussions following the post, and on Hacker News (https://news.ycombinator.com/item?id=9406465) are also well worth the read.
As I was reading, there were a few points in particular that generated additional thoughts that I wanted to speak to:
Lesson #1: “Start small, then extend”. The whole concept of a Minimum Viable Product is a primary one when working in an Agile development environment. It can save many headaches if the customer can be shown small pieces to ensure their initial vision still makes sense. All that being said, taking the initial lesson statement at face value is inherently risky. Striking the right balance on ‘small’ takes experience and a good grasp of where you want to get to. There are certain general overarching concepts that should always be kept in mind even when building a small piece. For instance, “How many concurrent users are we expecting?” The way we build our solution may be wildly different if the answer to that question is 20 million rather than 20! While that doesn’t mean we need to have a perfectly architected scalable solution right from day one, we do want to ensure we don’t get backed into a corner where everything needs to be redone. The John Gall quote from the initial post summarizes this nicely.
Lesson #6: “Everything takes longer than you think”. There is definite truth in that statement that I think most developers can attest to! Often the larger the scope one is considering the more apparent this becomes; this makes it very important that work be decomposed into smaller units such as Agile user Stories. It is much more difficult to estimate effort on something that is on a scale of months (or even weeks), than something on a scale of days or hours. The use of Agile estimating techniques, such as Planning Poker for User Stories and proper story tasking, can really help here.
Lessons #7 “First understand the existing code” and #8 “Read and run”. These are closely related in my eyes, and are invaluable advice for any developer. I would like to take these two lessons one step further and include ‘Read, run, and understand the Unit Tests’. A well written suite of automated unit tests can really help with understanding the code, and is one of the best forms of documentation there is. Its documentation value far surpasses that of source code comments, as those comments are often NOT updated with the code; they then not only become out of date, they may also be inaccurate – which can lead to misunderstandings and bugs. Unit tests demonstrate the expected functionality and are much more likely to be up to date, as any business logic changes would have required equivalent changes to the tests. So while it is necessary to understand the code, understanding the unit tests makes that a much easier task.
Lesson #11: “Reproduce the problem”. Although Henrik doesn’t say it explicitly I’d like to believe that when he states: “Then you make sure that when the fix is added, the problem is gone”, he is referring to writing a unit test. When a problem is discovered, one of the first steps should be to write an automated unit (or integration) test that reproduces the issue. Then after the issue is resolved, not only do we have an test to confirm the fix, we also have a test to alert the team if that functionality is re-broken at a later date (such as via a bad merge).
And finally, I wanted to add my own Lesson 22b as an addition to the wonderful advice of Lesson 22 “Keep Learning”.
Lesson #22b: “Keep teaching”. The two most common steps in learning are to first take in some new piece of information (often by reading or watching a video), and second, to use that new piece of knowledge (via practice). A less well known third step (and something I really enjoy) is to teach that information to someone else; there is often significant benefit for one’s own learning by doing so. A good phrase to remember is “See one. Do one. Teach one.” Not only will this enhance your own development, it will make the rest of your team better for it as well.