I listened to “Uncle Bob” Robert Martin talk about Software Craftsmanship on either the Software Engineering Radio or Pragmatic Programmer podcast. It got me thinking. I have been studying a lot of programming languages and technologies lately, but when was the last time I focused on pure coding itself? I was a like a painter learning about oils, acrylics and water colors – but it was time to focus on the cross-cutting techniques of painting applicable in any medium.
So I picked up his book – Clean Code, and summarized the contents to be able to repeatedly refer back it. A number of the things he covered I already knew from an earlier study group on Martin Fowler’s Refactoring book.
Understanding it intellectually was not going to be enough so I picked out one of the quizzes from the Ruby Quiz (Pragmatic Programmers) and tried to apply it. At the same time, I also decided to do full “Orthodox TDD”, where I did not do any development until I had a failing test. I worked through some design alternatives up front, and then proceeded with the one I liked.
It was slow going. I tried to be as true to the book as possible, and then meant a lot of refactoring as I thought of new ways to create cleaner code based upon the book. As much as I like Ruby, Java is definitely an easier language to refactor (but thank heavens for all the unit tests – a necessity in Ruby). I have seen a book out there on Refactoring in Ruby, and I may pick that one up.
But slow going is okay. When you study martial arts, you are supposed to go slow as you apply the techniques. With practice, speed comes later on top of perfect technique. In this practice scenario, I was doing just that. This was the major reason I was doing this on a home project as opposed to work, where speed is obviously more important.
More challenging than I expected was creating extremely well named entities – a lot of rename refactoring took place. Nonetheless, the number of comments I had in my code was extremely small – it was unnecessary as the naming told the story. I tried to follow his newspaper model of letting my code tell the story in various levels of detail – this worked out well in the end. Plus, the lack of comments that were not there that typically were “because they are supposed to be” made the code much easier to understand. It was better, and liberating.
I did struggle with some things. The breaking down of all the methods into small methods ended up with a lot of lower level methods. While the methods were extremely cohesive, there were a lot of them. A good signal to me that I had broken them down into too many sub-methods was the extreme difficulty I had in creating names for them to show their intent without using any type of synonyms. Based upon that, I recombined some of the methods.
I also struggled with his advice on not using return codes or error codes. In his statement, if your method performs a state change on the object and returns a return code, it is doing both a state change and a query, violating the cohesiveness of the method. By throwing an exception instead, the method is more cohesive and the consumer can write less complex code. Plus, if you refactor complex methods into multiple more cohesive methods, having to check for return codes permeates through each invocation, increasing code bloat.
Nonetheless, this seemed to run against Joshua Bloch’s advice in Effective Java on using Exceptions only for exceptional conditions as well as the overhead associated with them. I also did not like having to create a new Exception class as this seemed to increase the necessary mental model for code.
Then, I thought on the pattern typically found in Enumerators – a cohesive querying hasNext() method along with a next() method that either returns the next entity or throws an exception if one is not found. How many API’s had I seen lately where they had been modified to offer a similar query method, or offer variations of methods that either returned an error code or threw an exception. I am seeing the value, but I am continuing to work through this.
Overall, this is an excellent book to study. I will continue to apply it as I work with other technologies at home to improve my general coding abilities.