Thursday, January 23, 2014

Refactoring - the human factor

I talked to many people about the concept of refactoring recently. I've noticed a pattern. Not all team members are equally pro-refactoring.

I know how annoying it may be, when you're doing your best to improve the code, you learn how to do it the best way, you try to introduce it and then it's not only not appreciated, but also often rejected. Why is that?

There's plenty of reasons, but most of them come down to the fact that a project is a team work. In a team, we work with other people. We all share the same goal - to let the project succeed. However, we're humans - each of us has a different perception of the goal and the path that leads to this goal.

You may think that it's obvious that a better code will result in the success of the project. In most cases that's true.

You may notice different levels of the refactoring-scepticism.

Do we really need to change the existing code?

If you see such attitude, then one way of dealing with it is going back to the reasons for the refactoring. Is it because you spend a tremendous time on bug fixing? Is it because adding new features takes more and more time? Maybe it's because the app is slow and refactoring can help you extract some parts and later optimize them?

There's never refactoring for the sake of refactoring.

Whatever is the reason, make sure everyone understands it. If there's no understanding, move the discussion one step back. Why is it that your perception of the situation is different? Programmers are smart and logical people. Once you all see facts, metrics and numbers, it's easier to agree on the same solution.

Refactoring takes a lot of time

This is a fair argument. We all care about the time we all spend on the project. Even if it's you doing the refactoring, then everyone is aware of the fact, that this time has a cost.

The best way to deal with this argument is to keep improving refactoring skills. Both yours and your teammates. Examples from the Fowlers' "Refactoring" book are great. If you've done a quick refactoring, maybe it's worth showing to your team on a projector or record a screencast? 

What you want is to have the refactoring cost being almost negligible. If your refactoring changes are fast and safe, then it's quicker to make the change than to discuss it.

I wouldn't refactor this part

I made the mistake of refactoring the part of the code that wasn't really that important to change. It depends of the time spent. It's always good to improve the code everywhere, but what is the price? Does it take you 10 minutes, 1 hour? 10 hours? 10 days? Is it worth it?

Time is our currency, make sure we spend them in the best way.

I would refactor it differently

This problem appears when we have different visions of the refactoring. Let's say you learnt everything you could about DCI and you're sure that's the best direction to go with your project. You envision the contexts, the roles, the objects. Slowly, you keep extracting more code into modules that are later (hopefully) used as roles.

At the same time, your colleague kept studying the concept of microservices. His goal is to split the app into multiple services talking to each other via HTTP/JSON.

Where you see contexts, he sees services.

This represents an architectural difference between both of you.

To be honest, this is a nice problem to have. It means, that people in your team are passionate. They put time into learning new concepts and they are constantly trying to image the app in a different way.

How to deal with it?

I've chosen DCI and microservices as examples, but you could have a much different pair. What matters here is that most of the good architectures are not in fact that much different, however surprising it may sound.

If you want to go DCI and your colleague wants to go microservices, then you have more in common than conflicts. Putting behaviour in the modules, as a step into using them as DCI roles is also a step into the microservices direction (you split the logic in a way that can be used by the microservice, later on). Your main difference is probably the last step - really, that's a nice problem to have :)


One last thing, sometimes you may resort to another option:

Don't call it refactoring

OK, this one is controversial. In some teams, refactoring have negative meaning. It's probably for good reasons. Maybe they've had someone in the team, who didn't deliver value apart from endless refactoring? Try to understand it.

The goal is not to 'do refactoring', the goal is to do better, as a team.

If it doesn't help you, don't call it refactoring. Some teams are totally fine with the idea of The Boy Scout Rule, which means more or less the same as refactoring. Keep improving the code quality, don't call it a refactoring.


Summary

No matter what is the reason of the initial misunderstanding about the refactoring, make sure everyone understands it the same. Most of the times, there's something rational behind the refactoring need.


----

What you just read is an excerpt from my upcoming book: "Rails Refactoring: Service Objects". If you're a Rails programmer and struggle with an existing not-so-pretty Rails code, then you may find it interesting. At the moment, the book is 32 pages, full of code examples and with recipes how to safely, step-by-step improve your Rails controllers, even if you don't have a full test coverage. The beta sale will start very soon. 

If you have examples of ugly Rails controllers, then please, send them to me: andrzejkrzywda@gmail.com.

1 comment:

Martin Radhose said...

Hi! What about the post about Symphony 2? I'm really curious about your thoughts...