I have been a professional developer since 2008 but I had not read Code Complete by Steve McConnell before this year. Originally, I intended to read the book all the way through so that I could give tips to junior developers about which sections to read. I have changed my plan now that I have read the book all the way through. I think it would be better for junior developers to learn from more experienced developers on the job, rather than more rote book learning.
So why are we here?
I am not a junior developer anymore but I still learned a lot from the book. It covers many topics from basics of code organization to more complicated subjects like design and planning. Here are the topic that I found most useful.
Metaphors for a Richer Understanding of Software Development (Part 1, Section 2)
We all use metaphors to make difficult problems easier to understand, but I have never considered whether I was using the most appropriate metaphor for the situation. Knowing common metaphors in software development, when to use them, and when to look elsewhere for inspiration can help make a problem more manageable. It also sets a common language to discuss problems with other developers on your team.
The author mentions one metaphor about building software systems by accretion. It stated that build a system is like an oyster forming a pearl or land forming along the shore. I have done work on several large projects and I have seen the accretion metaphor in action. Programs usually start with a core set of functionality. New areas of functionally are added around the core as time goes on. With proper planning and design, you will end up with a work of art that can continue to grow over time.
Creating High-Quality Code (Part 2, Sections 5 – 9)
I have been developing for 7 years and feel I have a grasp on how to write and organize code. I have a way of setting up projects that works well for me. It is still nice to have a refresher now and again. I found the part on creating high-quality code to be a good representation of good code organization practices. Code Complete Second Edition came out the same year I graduated college, so I feel like Part 2 filled in some of the gaps that my professors were not teaching back when I was in school.
I found section 5 on design in construction especially useful. The author provides several suggestions on how much design is needed up front and suggestions on several design strategies. I have been on projects where formal documentation based on a template was required for every enhancement, no matter the size. I have also been on projects where the business requirements are the design. It is much better to have the appropriate amount of design before coding starts. Too much design can slow the start of a project, but not enough design can cause a bad fit between parts of a program when they come together.
Debugging (Part 5, Section 23)
Code Complete has many good points on debugging more efficiently, accurately, and making fixes more reliable. I found the part on psychological consideration in debugging to be very interesting. My favorite bugs are due to misspellings, forgetting to add brackets after an if-statement, or forgetting to add parenthesis around mathematical or logical operations. These can be hard to find because you might miss them when staring right at them. Good coding practices can prevent these.
Refactoring (Part 5, Section 24)
Any project that has more than a single development cycle will eventually need some level of refactoring. Knowing when, why, and where to refactor will make your code easier to maintain and avoid unneeded development cycles.
I was a part of the team that rewrote the back end of a web service on one of my projects. We redesigned from the ground up and spent a year planning and constructing. We have also been refactoring a little more with each release. Most of the refactoring we do fits well into the refactoring strategies in part 24.5. Every release we make areas of the code more maintainable, easier to unit test, and more understandable.
Code Tuning Strategies and Techniques (Part 5, Sections 25 – 26)
Do not tune the code just for the sake of tuning. Do not tune based on superstition or what used to help 10 years ago. Between today’s compilers and hardware, certain optimizations do not actually buy as much as they used to. Optimizations also tend to make code harder to read. Instead, identify the need for tuning in the first place. Identify the code that is using the most resources and then start optimizing.
One point I took away from these sections is to make sure you can measure how much improvement you are making. The compiler may be making the optimization for you already on code that is easier to understand. Your changes may not buy you as much as you thought they would. Your rewrite may make things worse. The author makes a good point that one single optimization may not be enough to reach the performance goals required. It may take many small improvements to make up the difference.
In either case, having a good code-profiling tool can help identify the hotspots in the code. I have had good results with Microsoft Visual Studio 2013’s built in code profiler to find expensive calls in .NET code. I have also had good results with WinDbg and SOS for finding memory leaks in .NET applications.
Personal Character (Part 7, Section 33)
I enjoyed the sections on Curiosity and Intellectual Honesty. I tend to stay very focused when working on projects but it is very important to find time to for learning. There are usually opportunities to do experimentation within your current assignment that you can use to learn more about new libraries and features. This is not enough. It is also important to keep up with what is going on in the industry by reading articles and blogs as well as attending training courses and conventions. You also need to be honest with yourself about what you know and where you need to grow. No one knows everything and thinking you do can blind you to where you need to focus on your education.
Themes in Software Craftsmanship (Part 7, Section 34)
The idea of writing code for people first really spoke to me. I learned in school to make the classes, methods, and variables be self-explanatory and use comments to fill in the gaps. I have learned over time that if the code in a method is human readable you do not need nearly as many comments and the code is easier to maintain. This is especially true when developers update the code but not the comments. I have seen plenty of cases where code refactoring eventually makes a comment obsolete because it no longer applies to the current state of the code. This is worse than not commenting because it is now misleading. Keep your code as human readable as possible. Your teammates will thank you.
McConnell, S. (2004). Code Complete (2nd ed.). Redmond, WA: Microsoft Press.