Before I rush off and refactor my code, I like to live with my code for a while. The refactoring I do in the TDD cycle is to get rid of trivial duplication and, perhaps, some better naming. I deliberately delay extracting methods and classes and pushing up or down. For me, those are quite important design choices, and I want to make those decisions only when I have a good understanding of my problem.
What do I mean by “live with it for a while”? Literally, I leave it alone and move along to something that is in it’s vicinity. I choose something that is close enough that will need to interact or modify the “living-with” code. This new use case, scenario or question is to further my understanding of the problem and I choose it deliberately. If it turns out to be tangential, I don’t sweat it. I just pick something else that will move me closer. The fact that my first choice was poor is always valuable insight into my lack of understanding of the problem.
Aside: The
simplicity of my solution is directly related to my depth of
understanding. The deeper I understand the problem, the simpler I can
potentially get. Shallow understanding leads to more complex solutions. This takes time, and “living with it” gives me freedom to play with the problem from several angles.
I don’t mean “ignore it after a while”. Ignoring it is like noticing a crack on your lounge wall and after 2 weeks of doing nothing about it, you don’t see it anymore. So, living with my code is not giving myself permission to be sloppy. It’s deliberate choice to look for a better, simpler solution as I increase my knowledge. Once I have a bit more knowledge, I can start making more adventurous design decisions. I think it’s almost impossible to find a simple solution if you don’t have deep domain knowledge.
It means that I refactor a little at a time frequently. Even if I know my code is not clean, I’d rather have a pulse for my code, and let it beat weakly. All I’m doing is constantly looking for little things that will make that pulse beat a bit stronger. I now realize that I refactor a little at a time, but almost continuously. I’m not searching for clean code. I’m searching for markers in the domain that confirm or refute my understanding. The clean code will come with time.
Living with my design for a while has saved me lots of time, especially when I’m not confident of my knowledge of the problem. Give it a try and let me know whether it works for you too.