make it work
make it right
make it fast
These statements are often quoted when it comes to discussions between software developers about software performance. Some people tend to emphasize "make it work" and leave the "make it right" and "make it fast" to the maintenance guys.
The statements should not be understood as
"Make the WHOLE SYSTEM work"
"Make the WHOLE SYSTEM right"
"Make the WHOLE SYSTEM fast"
Rather, I'd like to see it as a continuous cycle which reflects the modern development iterations:
"Make the CLASS work"
"Make the CLASS right"
"Make the CLASS fast"
"Repeat with next CLASS"
Of course, the term CLASS is supposed to stand for every type of artefact, such as a single compilation unit, classes, interfaces, enums, configuration files, sql scripts, components etc.
So what does it mean?
After I've implemented a class and its relatives, in which I include test cases and the bare minimum of javadoc, the implementation "works". At this point, it has proved itself by one single use case, which was the reason why it has been implemented in the first place. Hopefully, there are additional unit tests covering the corner cases, so some additional use cases may be covered, too. That's the state in which code often is incorrectly declared as being "finished" by the author of the code. We have to understand that actually, this is the state of "it works" and nothing more.
Hence, to make the code "right", we need to do a lot more:
- even more tests for corner cases
- write complete documentation, which includes examples of usage as code snippets, references to other related classes and documentation
- review it together with a team member. Either answer his questions or take his questions as an opportunity to ...(see next item)
- refactor the code to make it more readable and more intuitively understandable.
- refactor again to make it even more readable
- refactor it again to make its design more reusable. Apply principles like "Open-Close".
- rewrite and update the documentation, so it is more independent of the actual implementation and provides the reader of hints how to use your class, not how it works internally.
- rethink the physical attributes of the class, e.g. the location - should it be moved in another package or artefact? Should it be renamed to a better name?
- and more. see books like Clean Code by Robert C. Martin for useful hints
That is to make it "right". Only these steps distinguish crappy code from clean code written by a professional to be read by other professionals. Yes, I know that pressure like time and budget often stop us from producing high-quality code. Like "We'll document it later" or "We'll clean it later" - they're excuses for not doing it at all or move it into the future where we've long gone, left the project and put other people in charge of maintaining our code.
Uff, that's a lot to do. Anything else?
Yes. Then, we can go on and try to make it fast. However, since we already have clean code which is readable and thourougly tested, we can be pretty sure how to improve performance without breaking it. We can try out all kinds of creative solutions and be confident to not break existing logic, as it's covered by test cases. And we know that the design is beautiful, so we can identify slow parts very easy in JProfiler. For example, by breaking up code into smaller when we made it more readable, that now becomes very handy. The more distinguishable methods we see in profiler statistics, the better we can calculate aggregations and filter for interesting stuff.
And since the design for every class meets the same quality level, we easily can make refactorings to improve performance. Architectural decisions which impact performance are very hard to revert, so at least it is advisable to make the code itself als clean as possible, so we "see" performance bottlenecks more easily. If they're burried down in unreadable spaghetti code, we'll have a tough time to find culprits.
Then and only then we should declare our code officially finished and move on to the next task. And I believe that this is the state of code my boss wants to have when he asked me to implement something which must meet certain criterias required in a enterprise environment:
- correctness - make it work
- robustness - make it right
- stability - make it right
- quality - make it right
- maintainability - make it right
- scalability - make it fast