Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

> best refactoring is usually done in small increments.

Yes. And contrary to many people, I'm fine with the (eternal?) limbo that we then end up with: parts of the codebase using the new stuff, parts still using the old stuff.

I actually prefer that. Just add proper documentation, if the language/framework supports it: add deprecation notices and move on. Through e.g. "refactor on touch" we can move the old code to the new if we are there anyway, changing other stuff.

Sometimes I'll find that after a while, the old code is used so rarely that now's the time to just rip it out entirely - a small refactoring. Sometimes I'll find that the important pieces - important business logic, critical performance path, often touched code, exposed parts etc - can be changed to use the better/more-performant/more-testable/safer code. I think just leaving the last 10% is preferable over postponing the entire refactor untill we can also move the last 10%.

It's part of what I tend to call "Continuous Incremental Refactoring".



view as:

> add deprecation notices

one thing that I think needs to be more common is that you should not write simply "this method is deprecated".

You must always say "...is deprecated *in favour of* FOO".


yes!

And it's one of the first things I'll add to the lib/framework/tools/utils if it doesn't exist: a mechanism to mark code deprecated. It should require a description, the item that should be called instead, and optionally a URL and optionally a time/version after which it will be considered an error instead of a warning.

The deprecation should be configurable (through ENV vars, e.g. DEPRECATIONS=fail|warn) so that I can run a test-suite or some local dev env and have it blow up when it hits a deprecation. Useful for when working on them and to raise awareness.

Such a method/macro/function/annotation isn't that hard in most languages: just a proxy calling the deprecated method with the arguments passed in and then formatting a message and logging or raising that.


> And contrary to many people, I'm fine with the (eternal?) limbo that we then end up with: parts of the codebase using the new stuff, parts still using the old stuff.

That is fine when, as you described it, there are only two types of code: one still using old technique/technology A and the other using newer version B.

Where it becomes a problem is when you haven't finished the transition and realise you need to start moving on to C, or you leave and the new person doesn't understand the difference (and probably also has their own desired replacement). Before you know it, you have three or even more styles of code in play at once, with diminishing ability to keep moving to the latest version. This is sometimes called the lava layer antipattern [1]

[1] https://mikehadlow.blogspot.com/2014/12/the-lava-layer-anti-...


It is an antipattern. But IMO still better than "feature freezing" for months, delivering nothing of (business) value for weeks or months, working like madmen trying to remove the last 10% of the old code - which by the 90/10 rule, costs probably 90% of the budget.

I'd rather have three or four versions - provided these are marked well, documented, and so on. Even if the codebase uses four versions, at any point in time, there is still only one thats the right one today.


The part I find hard convincing people of is not that this is a good idea but that it is always a good idea and always possible.

Everybody thinks it's a good idea. But, their particular problem is a special snowflake that requires a big bang refactor and there's just no way around it.


It's funny how many people push for big bang rewrites and how few people have actually seen a successful big bang rewrite.

I've been at 5 shops across nearly 20 years. I've been on teams mired in promising to do a big bang rewrite of our own system. I've been on teams that had competitive teams hired to try to replace our system. I've never seen it work, not once.

It is a herculean, multi-year, double-your-current-budget effort requiring you to throw most of the functionality of your existing system out the window. It just never works out.

The naiveté is incredible. I've seen promised 6 month rewrite projects escalate into 2 year projects, and fail.. leaving the existing system live another 10 years.


I've worked on many "Big Bang Releases" and consider all of them a poor choice.

Even the single one that was a huge success: in hindsight, I would've rather migrated that through the strangler-vine-pattern¹. Yes, it worked out fine. We even managed to migrate it rather in budget and on time. The release went OK, and we didn't experience crucial data-loss or lost customers. So by all metrics it was a success. And even then: I won't do it like that again. Because part of the success was just random chance: if the dice had fallen just different, it would've been a much worse migration. And I don't like leaving such stuff over to chance.

edit: ¹ https://martinfowler.com/bliki/StranglerFigApplication.html


The thing I am seeing there is rather a dislike of the codebase than a desire to rewrite.

My rule of thumb is this: you need to touch a codebase _more_ to throw it away.

Tell that to whoever wants to rewrite. You will have to maintain the old application anyway (yes, this is a given, you are not getting an exemption for security holes) and you will have to de-risk the project by providing value (== release early, release often, continuously switch parts over - which requires work on the legacy side, too).

If someone wants to do a big bang rewrite then you need to fight for the importance to touch the "legacy" codebase. That is the actual reason why people are so religious about their rewrite.

Other than that: same thing, ~20 years and nothing good comes out of big bang rewrites and releases.


That's what one should do, but I generally see the incentives setup all wrong.

The most common scenario is that the fresh young smart ** hoodwinks the boss into giving them 1-2 years and 2 subordinates to help them do the rewrite in isolation. They come off all support rotas and have no responsibility for BAU operation of the old codebase. The old codebase is left with usually a same or larger team maintaining and still adding new features.

The other way I've seen this done is that senior management really wants the rewrite, shops around for a candidate internal or internal who promises to do it.. and then basically same setup as above.

Setting up an explicit "good" and "bad" team creates awful vibes, the "good" team never delivers and starts exiting as accountability starts to creep in.

Meanwhile the "bad" team hemorrhages staff continuously from the burn out of maintaining the old thing with less people while also being told your job has an expiration date.


Legal | privacy