Hacker News new | ask | show | jobs
by jlongster 3052 days ago
You need to tell your manager that it's simply impossible to both clean all that up and also make progress on the project. You need to stop the erosion in order to fix it; fixing will require fundamental changes that will absolutely block progress. If aren't able to freeze the project, your cleanup progress will be constantly thwarted by new ugly hacks.

There's just no way around it. If your managers won't freeze the project until you make meaningful progress, you're going to be stuck working with this ugly code for a long time. Try to convince them that in the long-term a cleanup will pay dividends. Without their support though, you won't get anywhere.

If you're able to freeze the code for a bit, it sounds like it might just be quicker to rewrite some parts like the CSS. Don't take on the whole project at once - find pieces that can be rewritten individually, even if it's a large part like all the styling.

3 comments

I disagree with most of this comment, but I think it's an interesting and valuable discussion.

Here's where we agree: You need to stop the erosion in order to fix it. Every developer on the project needs a shared vision of what "better" means. For example, the parent comment mentions React components that manipulate global variables. First of all, everyone agrees to stop doing that, and agrees on the alternative (use props, a redux store, whatever).

But you don't stop the world and rewrite to the new standard. Instead, you apply a strong "boy scout rule" to every code change. If a developer modifies a small component, they also need to remove the global references. If the existing component is large, the developer must extract a smaller one, and the new extracted component must meet the new standard.

This will slow your velocity - at first, by a lot. But you never stop delivering entirely. You never waste time rewriting things that you would never touch again anyway. You also learn along the way - because while "don't use globals" is pretty universal, most architectural decisions are not. You will find that the "clean new standard" changes to match your application. At the same time, everyone on the team learns about the new standard, and buys in to the new way of doing things. There isn't a "new system" with the cool kids, while the B-team strings along the old one and waits to be laid off.

That's what I've always done. Fix it when you see it. Eventually, you have a clean codebase.
I've mixed feelings on this still. It leads to big code reviews, with most of the changes being less important. So I rather like the separation, spend some time just for cleanup. Maybe take notes on wins as you see them but you don't need to do them yet (or put them in the same review as another bug fix / story item).

If you're using git and can separate things out cleanly then I think fixing it as you go would work better. I yearn to use git every day again...

Well, I'm not talking about a major refactor (squash them when you see them). This should be an enum, this is named poorly, this variable is scoped wrong, inline sql when should be a sproc, that kinda stuff. A few lines a fix, the low hanging fruit.

Major refactors certainly need to be accounted for in a sprint(s), but keep features a priority when needed in sprints.

Unfortunately there are business reasons why freezing the code is impossible. We’re ecommerce and working on a timeline dictated by consumer behavior. So if we need a promo tomorrow it’s going live or else we’re not making budget. I kind of assume this is how we got into this state to begin with.
And unfortunately nothing will change because what you want to do is better in every single way, but their way of doing thing is better in the only one that actually counts: It's faster and cheaper.
My assumption is that I will never clean up this entire codebase. Rather, I’m looking for the best way to triage the situation: what are the things I can/should try to fix first?
Make your problem their problem.

Make a list and organize all the things you'd want to change. Untangling balls of mud often take on the order of months to start seeing any kind of progress. You have to make sure you keep things organized over a long time otherwise you can't tell whether or not you are making progress.

If a module breaks often when seemingly unrelated things change or breaks every time someone touches it it's easy to say the module is badly written. It's often hard to say why it's bad and harder to say how to fix it. However at least you will have data and be able to defend your position that messy code in a particular module actually slowed down the addition of a new business features.

If you are using a bug tracking tool (Jira, Bugzilla etc) make a bunch of private ones for yourself. If management doesn't like all your private tasks showing up on reports then try to get a section for yourself or see if you can deploy your own "private" bug tracking instance.

Any time you encounter a problem make a bug for it even if you have no solution. If upgrading a library version a minor version causes a break make a bug for it etc. You'll start to see patterns and then you can make small but really important surgery on the code. You can have a plan for how to fix a particular module when the time arises.

For example we had a core module with some 190 downstream internal clients across some 5 different dev teams. A recent Oracle version upgrade caused problems because we would have to to coordinate everyone to update at the same time. I already had a long time standing issue that the module is poorly organized and already had a list of all the things that were wrong with it. When this issue came up I immediately stepped in and how to completely remove Oracle from the core module so that the downstream clients can each upgrade on their own time. Because I had thought about this for time I was ready to defend the proposal by showing it would take less time to do this. I was able to do a refactoring I've been wanting to do. Over time people will start to listen to you more if you are actually delivering shit on time. Otherwise, even if your complaints are correct, you will be labelled as just a whiner.

Write down everything you know about the codebase. Whenever you discover a surprising dependency or behavior make a note of it. This is something you can do in passing as you push features.

At some point you'll start recognizing structures in the code some of which will be small enough to surgically improve.

How will you make sure that you are not introducing regressions in such code base? You cannot add unit tests because it is probably untestable mess. So instead of some uncertain dividends, which may or may not materialize, you introduce real risk of breaking already existing stuff.