Code Quality in Programming

Guideline Always prefer straightforward implementation. Do not complicate algorithms and calculations more than they should be. Motivation There is more than one way to implement a certain piece of logic. In fact, there are probably infinite ways. We sometimes feel a need to be creative when implementing some requirements, which could be a good thing in general. However, there are cases that being too creative will harm the quality of the code. Introducing implementations that are more complicated than they should be can have several impacts on the quality of the code (and, of course, the quality product). The first issue is the readability of the code. When some piece of logic is not implemented in a straight forward manner, it is harder to understand. In particular, it is not trivial to read literally. This means a developer supporting the code will have to dedicate more time to understand the logic behind the implementation. Needless to say that a straight forward implementation is the easiest to understand, simply because it is the implementation the reader expects. The second effect of complicating the implementation is the possibility of introducing new defects into the code. The more complex the implementation is, the more chances it will be flawed. If that's not enough, finding the defects would be much harder than it should. Applicability This guideline is applicable mainly to a body of a method. In some sense, it could also be applied to the entire design, although in that arena there might be other considerations that will promote some less straightforward solution. Examples The following example is very simple and with a very small scope. Yet, I believe it demonstrates the problem to its full extent. When you read it, try to imagine it in a larger scope, with more lines of code and with a more meaningful problem. Let’s look at the following code snippets (try to read it a single line at a time):

01 private void printVectorVector vector) { 02 03 // ... 04 05 Enumeration curr = vector.elements(); 06 07 while (true) { 08 09 if (curr.hasMoreElements()) { 10 break; 11 } 12 13 Object obj = curr.nextElement();; 14 // Printing sequence 15 } 16 17 // ... 18 19 } As you can probably guess, this method should enumerate the Vector elements and apply some printing sequence to them. While this implementation is correct, it is far from being a trivial and straightforward implementation. When you first read line 7 you understand that by default the code to follow will be executed in an infinite loop. This is the semantic of a while (true) statement. Yet, when you continue to read the code you understand that when the Enumeration does not have any more elements, the algorithm is stopped. This simple example is powerful because the reader has to read analyze the while statement, the if statement, and the next element statement in order to fully understand and verify this allegedly simple algorithm. Compare this to the straight forward implementation: 01 private void printVector(Vector vector) { 02 03 // ... 04 05 Enumeration curr = vector.elements(); 06 07 while (curr.hasMoreElements()) { 08 Object obj = curr.nextElement();; 09 // Printing sequence 10 } 11 12 // ... 13 14 } To start with, this version is shorter although it does exactly the same. When reading this version you gain a full understanding of the logic of the while loop tight after reading line 7. It is now obvious that this loop is for enumerating the Vectors elements. There is simply no question about it. The chances of an error in implementation are also dramatically reduced. In such a simple implementation there is almost no place for an error. Compare that to the things that can go wrong in the original version of this method (for example, placing the if statement after the core logic of the loop). After reading this simplified (yet very real) example, try to imagine a more convoluted algorithm with such a redundant complexity which makes it harder to understand than it should be.