Thursday, June 27, 2013

[en] Code Speaks To You

A colleague asked me to translate this post for some non-Polish fellows. I've been thinking about blogging in English for couple months. Some guys from Polish blogosphere have already done so. Who knows, maybe this is sign of times. Let's this one be my first small step.


So, I had an idea for a code readability criteria: code should speaks to you. I took this sentence very seriously.

Take code piece you want to challenge and:
  1. Replace all operators by words.
  2. Replace a "{" following "if" statement by "then".
  3. Split camel case names into words.
  4. Take only right "=" operator argument. Ignore the left one.
  5. Treat each line of code as a sentence ended with a dot.
  6. And now paste the given text into Text-to-Speach engine .
  7. So if you understand (without looking at the code) what you hear, the code is readable.

Let's we try with the following code.
public class List {

 private final static int DEFAULT_SIZE = 10;
 private Object[] elements;
 private boolean readOnly;
 private int size;

 public List() {
   elements = new Object[DEFAULT_SIZE];
   size = DEFAULT_SIZE;
 }
 
 public void add(Object element) {
   if (!readOnly) {
     int newSize = size + 1;
     if (newSize > elements.length) {
       Object[] newElements = new Object[elements.length+10];
       for (int i = 0; i < size; i++) {
         newElements[i] = elements[i];
       }
       elements = newElements;
     }
     elements[size++] = element;
   }
 }
}

Challenging the add method we would have a text similar to this:
If not read only.
Size plus one.
If new size greater than elements length then.
New objects size of elements length plus one.
For each elements: i of elements.
New elements.
Element.


Now paste the text above to the Text-to-Speach engine and listen :) Does it make sense?

After small refactoring of the add method it looks little bit differently.
public void add(Object anElement) {
  if (readOnly) {
    return;
  }
  
  if (atCapacity()) {
    grow();
  }
  
  put(anElement, into(elements));
}
 


private Object[] into(Object[] elements) {
  return elements;
}

private void put(Object anElement, Object elements[]) {
  elements[size++] = anElement;
}
 
private boolean atCapacity() {
  return size + 1> elements.length;
}

private void grow() {
  Object[] newElements = new Object[elements.length + 10];
  for (int i = 0; i < size; i++) {
    newElements[i] = elements[i];
  }

  elements = newElements;
}

This time the text would look a little bit different:
If read only then return.
If at capacity then grow.
Put an element into elements.


Again, paste the text above to the Text-to-Speach engine and listen what your code speaks to you. Better? :)