Wednesday, October 3, 2018

Procedural and Environmental Approaches

I have a friend, Eran Pe'er, of DevCraft, who likens refactoring to the procedures and preferences of Brazillian Jiu-Jitsu. I don't know much about Brazillian Jie-Jitsu but I know about this way of thinking.

Every situation has a list of situations that are better than it. The transitions between certain situations are well-defined and can be learned, practiced, and shared. It's a good analogy for a style of refactoring. In this style, it is the procedures of transformation which give us our safety. A nice property of this is that it is environment-independent; you can do it with or without a meaningful battery of tests.

A tough guy threatens another guy with a gun, telling him to give him his wallet. The other guy takes the gun from him, hurls him to the ground, then tells the tough guy to give him HIS wallet.
A procedure lets you make your situation better in a relatively-predictable way
I have a different approach; this was especially the case before I met Eran. For me, getting to the suite of comprehensive, executable specifications is what it's all about. For new code, that's easy. I just don't write any behavior before I've written a test. For legacy code, it can be more challenging. However, once I've attained the right body of tests for some code, I can refactor with impunity.

I don't care if my changes are proved to be transformative because, with NCrunch, I'm always about three seconds from finding out whether or not they were safe. For me, the focus is on creating an environment where refactoring is always safe regardless of how disciplined an approach I take.

A man threatens another with a gun, demanding his wallet. The other guy gives him the finger. The bad guy shoots but the bullet bounces off a force field. The bad guy scratches his head while the good guy gives him a double-dose of the finger.
The right conditions make certain problems irrelevant
This difference in emphasis is interesting to me. For one thing, they both have a common ancestor: culture. Neither of these methodologies can be installed without a fertile culture. For another, they both work.

A lot of people would look at two things that work and ask "which one works better?" A seemingly-natural impulse for us is to make two ideas compete so we can choose a winner. My inclination is to find a way to combine them into something new - a third option that keeps the best benefits and leaves behind the worst drawbacks.

I've been experimenting with applying discipline-focused refactoring to my own work. To be clear, I'm not giving up what I already do. I'm just adding his style to the way I already work. I'm not sure it's speeding me up but it's also not slowing me down and I've only just begun to practice it. With a few more weeks, familiarity will develop and it may well be faster.

There's something interesting there. You can combine them (at least in one direction) without any slowdown. There's a compatibility, there, that implies they are complementary techniques.