One of my personal passions is to improve my productivity as a software developer. As part of this process I do a fair bit of reading and thinking about how individuals and teams create good software. Since this is a baby blog, I figure it might be a good idea to write down my ideas about what "good software" looks like.
Like any other human endeavor, software development is kind of messy. We don't communicate well; we make mistakes every day; we are horrible at predicting the future; we make irrational and imperfect decisions. But we still manage to succeed, and occasionally succeed brilliantly. Developers who are the most effective -- who succeed brilliantly -- have learned how become really good at creating good software.
So what does good software look like? Yes, the answer is in the title of this post, and yes, I came up with those three words because I like alliteration. Good software has the attributes of correctness, clarity, and changeability.
Correct means satisfying the needs of the customer. If it doesn't do what the customer needs, it isn't correct. In development-speak, this means the software satisfies the functional and non-functional requirements. Functional requirements are the 'what' of the software; the list of features; the things I can do with it. Non-functional requirements are 'qualities' of the software; things like security and performance and robustness and availability and usability. Correctness is often subjective, which is why there is a lot of discussion about whether some program ought to be more bug-free, or have more features, or be more usable, or be more responsive. So it is important to understand how we are defining correctness when we talk about whether a piece of software meets requirements.
Clear means the code, build scripts, shell scripts, database queries and scripts, internal documentation, and other bits necessary to create the software are as easy to understand as possible. The source should be self-documenting and well-organized, so that its behavior and purpose are obvious. Self-documenting code is obvious in its intent. It's characterized by meaningful names; constants instead of magic numbers; a distinct lack of side effects. Self-documenting code makes it easy to answer the question, "What does this code do?" Well-organized code makes it easy to answer the question, "Where is the code that ...?" This means the package (namespace) structure is clear; classes in each package are closely associated; structural and behavioral associations and dependencies are easy to find.
Changeable means that the software is as easy to change as possible. We should be able to implement new features and refactor to support new requirements with a minimum of effort. Good design and a solid test suite go hand in hand with changeable software. Good design makes it easy to make changes and still have the system compile. A good test suite makes it easy to make changes and still have the program work correctly. Use the principles of GRASP and SOLID, and write good unit tests, and you'll have software that can be changed with a minimum of effort.
So how do we create software that is correct, clear, and changeable? The best answer I have found is in the principles of agile development. Agile development
works well because it has the ingredients necessary
for a team to be effective and productive over time. Or to put it another way, agile methods lead to software that is correct, clear, and changeable.