Download EPUB

Book Summary: Code Complete

fagnerbrack.com 3 min read Original article
Summary
A summary of the book Code Complete with added notes from experience. Plan and design before coding, but avoid Big Upfront Design and Analysis Paralysis on Agile teams. Write clean, self-explanatory code with meaningful names like userInput and totalAmount instead of a or x. Use comments for the why and self-documented code for the how.

Build well-defined modules and hide implementation details. A database module with a clear API lets you swap database engines or use an in-memory array for unit tests. Refactor often to improve structure, readability, and performance. Refactoring changes structure without changing behaviour, and tests are the best way to prove behaviour stayed the same.

Anticipate errors with validation, try-catch blocks, and null checks. Test at the unit, integration, and system levels. Do code reviews to share knowledge and catch issues, but reviews can come too late. Pair programming on one screen and one task gives feedback earlier and builds a shared mental model.

“Code Complete” is a comprehensive guide for software developers that focuses on improving the quality and maintainability of code.

This post provides a summary, and I elaborate on some points based on my experience.

Design and planning

The book emphasizes the importance of thorough planning and design before writing code. This includes understanding requirements, creating detailed designs, and considering potential issues to minimize problems during implementation.

A developer creates a detailed design document for a new feature, outlining the overall architecture, classes, and methods, as well as defining the interactions between components.

Although the upfront design is essential, even on Agile teams, be careful with the trap of the Big Upfront Design and Analysis Paralysis.

Writing clean and maintainable code

McConnell advocates for writing clean, self-explanatory code with meaningful variable names, proper indentation, and consistent formatting, making it easier for others to understand and maintain.

For example, instead of using cryptic variable names like a or x, developers choose descriptive names like userInput and totalAmount to improve code readability.

Code comments and documentation

The book emphasizes the importance of providing clear and concise comments in the code, as well as creating and maintaining proper documentation to help future developers understand the system and its purpose.

A developer adds inline comments to explain complex logic and maintains up-to-date documentation describing the overall system architecture and individual modules.

Don't overuse this advice. Self-documented is always better than comments. Use comments for the "why" and self-documented code to document the "how".

Modularization and encapsulation

McConnell recommends designing code with well-defined modules and encapsulating implementation details, allowing for easier maintenance, testing, and reuse.

A developer creates a separate module for handling database operations, encapsulating database-specific details and providing a clear API for other parts of the application to use, like a Repository. This way, you can change database implementations and even use an implementation that simply saves the rows to an in-memory Array for unit tests.

Code refactoring

The book stresses the importance of regularly reviewing and refactoring code to improve its structure, readability, and performance, ultimately leading to higher-quality software.

A developer identifies a section of code with poor performance and refactors it by optimizing algorithms and reducing unnecessary calculations, resulting in improved efficiency.

Please be aware refactoring is changing the code structure without changing its behaviour. If you change the behaviour of the code while changing the structure, that's NOT refactoring. Tests are the best way to ensure the behaviour is not changed, only the structure.

Error handling and defensive programming

McConnell highlights the value of anticipating potential errors and implementing proper error handling, as well as employing defensive programming techniques to create more robust and reliable software.

A developer validates user input to prevent unexpected behaviour, uses try-catch blocks to handle exceptions, and adds checks for null or invalid values throughout the code.

Testing and debugging

The book covers various testing techniques, including unit testing, integration testing, and system testing, as well as effective debugging strategies to identify and fix issues.

A developer writes comprehensive unit tests for individual business domain models, ensuring they work correctly and can be safely integrated with the rest of the system.

Code reviews and collaboration

McConnell emphasizes the importance of code reviews and collaboration among team members to share knowledge, identify potential issues, and improve the overall quality of the software.

A development team conducts regular code reviews, where members provide constructive feedback on each other’s work, leading to better code quality and a more cohesive team.

However, the review might come too late, and one of the devs might have built up code on an assumption that goes in the wrong direction. Pair Programming the task from beginning to end in one screen and one task allows for the feedback to happen earlier and for both devs to build a mental model of the problem so they can perform better over time.

By applying the principles and best practices outlined in “Code Complete,” software developers can enhance their coding skills, create more maintainable and reliable software, and ultimately deliver higher-quality products.

If you liked this, you might like readplace.com, built for exactly this kind of reading.

Thanks for reading. If you have some feedback, reach out to me on LinkedIn, Reddit or Github.