I’ve been helping out with interviews recently at Atomic, and one question I tend to ask candidates is: “What does good code look like?” I thought that this would be a softball, a question that any candidate with a love of the craft would breeze through. What I’ve found is that even developers who write really beautiful code often don’t have much of a response to the question. So here’s mine, in four points.
Good Code Is Lucid
When I look at code, I want to be able to read it quickly and understand its logic immediately. This of course means the code should have consistent formatting and spacing. It should have clear and accurate names for modules, classes, and methods. It means I’m looking for the code to be organized in small, digestible blocks of code rather than hundred-line monstrosities. The API should model the problem space cleanly so that application logic is expressed in the language of the domain, and so that component roles are easily understood. It also means that the code has been regularly pruned – I shouldn’t spend time reading and understanding code that’s no longer in use.
Good Code Is Organized
When I look at code, I want to see attention paid to the structure of the application and its modules. Are packages huge bags of classes? Or are related objects clearly and carefully separated into namespaces? Has dependency inversion been respected? Can I quickly scan the repository and have a good idea of where to look when I need to find something? Is it fairly easy to extract a component from the project and use it in another?
Good Code Is Testable
I wrote a post a while back explaining what I mean by testable code. It’s extremely important that you are able to regularly and thoroughly validate the quality of your software, and I don’t like to see code that violates the basic rules for testability. Good code should inject dependencies, prefer pure functions, minimize side effects, and decouple components as much as possible.
Good Code Is Simple
As Rich Hickey describes in Simple Made Easy, great code is, well, simple. Functions or classes should have a single responsibility. They should have small, tight APIs. Modules should minimize dependencies and publish the required API for those dependencies. A function must not depend on the implementation of another piece of the application in order to behave correctly. Code simplicity takes planning and hard work, but nothing pays bigger dividends for the long-term health of a codebase.
So that’s my five-minute response. What do you prioritize when evaluating code quality?