This week I finished reading Refactoring and started to apply some more basic refactorings to Redmine. The end of Refactoring was as interesting as the beginning and Kent Beck's final chapter was really insightful. The refactorings that I applied to Redmine were more good practice at using simple steps to improve the design. Mostly, I focused on composing methods.

Refactoring, Final Chapters

The final chapters of refactoring were interesting. William Opdyke's research into refactoring and his chapter on it had several interesting pointers and thoughts on the practice of refactoring from a research perspective. One really interesting nugget of knowledge is that refactoring is a play on the mathematical term factoring.

A factoring is a way to write a mathematical equation: factoring is applied to equations in order to increase the readability of that equation in that context. For example, Newton's second law is famously known as F = ma. This is correct, but is a factoring that makes it easier to understand in the context of which it is presented (the general public). Newton actually described F = d(mv)/dt or as the rate of change of an object's linear momentum.

Kent Beck's chapter was also very good. Kent expounds the importance of refactoring as a (very powerful) tool in a developer's toolkit. However, after reading a whole book about refactoring and how it improves your code, your efficiency, the world, the universe and everything, Kent says that one of the most important aspects about being good at refactoring is knowing when to stop. Developers will often have an end goal when they refactor and that is wonderful. However, sometimes that end goal becomes too difficult, too costly, too ideal to accomplish and the developer has to make a decision: keep the refactorings or toss them. In general, the refactorings will have improved your code but sometimes the best thing is to just toss them (especially if you were regressing the code in order to make something magical happen).

As I read Beck, I wish I had the confidence to know when to stop and when to keep going. After reading that chapter and going through the refactorings to Redmine, I found myself asking "Is this too much? Or have I just barely scratched the surface?" It was difficult to judge where in the spectrum I was at any given time. Hopefully the rest of my experiences with this independent study will give me some insight into this question.


Switching gears, I went to a Ruby on Rails project called Redmine. Redmine is an open source project management suite. I like Ruby. I really wanted to learn how to effective refactor in a dynamic language such as Ruby (hint: its not that much different, you just need *really* good tests). Redmine was a good fit because it had a significant test suite for a significant sized Rails project. What I learned was that Rails doesn't lend itself as easily to the spaghetti code monster that was the Android function, but refactoring can improve the readability of code just as much.

Step 1

Extracted a Method.

Step 2

Extracted a Method.

Step 3

Split a Method. :find_project was doing more than "finding (a|the) project", it was finding a board associated with the project. So I split the method.

Step 4

Extracted a Method. Moving to a different area of the code (was satisfied with the other file), I found the account_controller. There was some duplication so I extracted a method.

Step 5

Removed redundant code (Rubyisms).

Step 6

Then I had some trouble. So I talked myself through it and extracted a couple methods to make sure I was sane while I was doing it. My stream of consciousness thoughts are written in comments.

Step 7

Removing redundant code. else -> if can be merged to elsif

Step 8

Adding guards. I could add guards, remove return statements and make the code read better. Yes, yes and yes.

Step 9

Extract method and Add Guard. This little combination was just cool. I took a long if statement, extracted it to a method with a good name, and used a guard instead of a if block. Much cleaner.

Step 10

Encapsulating. Just something I forgot to do correctly the first time.

Step 11

Add Guards. These guards are more expressive than the guards that originally existed. Cool. I like expressive.