HACKER Q&A
📣 UncleOxidant

How do you deal with code frustration?


Not gonna go into a lot of details of what I've been tasked with (someone I work with might recognize the task :). Suffice it to say that a lot of technical debt was built up over the last couple of years during a "move fast" phase and I've been called in and tasked with cleaning it all up and simplifying things that had become overly complicated (a bit of an understatement) because they keep tacking more code onto the edifice in an attempt to keep it standing instead of addressing underlying problems. I'm finding it exceedingly frustrating and after a couple of months I'm wondering if the task is even possible (primarily because the target keeps moving as more code gets added). There are multiple languages (at least 4) involved and lots of little files that get passed between processes running in different langauges that get parsed... ok, not gonna say anymore about that...

So programmers of HN, how do you keep from getting overly frustrated by a big ball tangled code? At what point is it best to just throw in the towel and suggest that perhaps they need to start over?


  👤 genezeta Accepted Answer ✓
For me, that point of surrender is not set by the code itself but by the people involved. That is, the code may be bad, terrible, horrific even, but if the team is actually willing to make the effort of improving themselves along with the code, then we can make it work, together. On the flip side, if the team is comfortably set into bad habits, has become comfortable or accustomed to the projects quirks and kludges, and is not really interested in changing their ways, then it won't matter how much effort you, alone, make and you may be better off giving up.

As for the simpler day to day frustration... well, remember that to untangle a messy knot you will need to make a lot of very small steps before you reach a position in which you can pull this or that string and finally see a bigger advancement. But those very small, careful steps are as important -or probably much more important- as the bigger one.


👤 sparker72678
1. Build tests (if you don't already have them) so you can refactor with confidence that you haven't created new problems.

2. Break into milestones so you can see progress. Celebrate the wins.

3. Find another developer to help out — you can bitch to each other, rubber duck ideas, and avoid some of the loneliness.

Even with these ideas, it can still just be nigh impossible to refactor if not enough resources are devoted to the task. Best of luck to ya, though!


👤 scrapheap
You're right to be worried about having more developers adding technical debt. If they're doing that slower than you're clearing it up then you'll eventually finish your task. However, if they're doing that at a faster rate than you're clearing it up then you'll never get there.

Starting over from scratch always sounds tempting, but in my experience it's only effective if the underlying architecture won't support what you need the system to do. Usually it's better to work with the existing codebase and slowly clean it up (check out Working Effectively With Legacy Code by Michael Feather for some great advice on ways to tackle it).

The best way to deal with this is to get the other developers involved in cleaning up the codebase. If they tidy up the area they're adding new code to then it'll soon get cleaned up in the most important areas (the ones that are having to be changed regularly).


👤 JonChesterfield
It's much quicker to add complexity than remove it. Dedicating some devs to cleanup while others continue trashing the code seems unlikely to work.

An argument against starting over is the same organisation that built a mess the first time is at risk of building a similar mess for version 2.

You might do better by moving to the feature work side of that conflict.


👤 brudgers
If you aren’t being paid, it might make sense to find a more fulfilling hobby.

If they are paying you it is probably to deal with the mess.

Assuming you are being paid, “this is hard work” usually isn’t a sound business case for scrapping a functioning operational component.

Good luck.


👤 amiga1200
Refactoring to patterns by Joshua Kerievsky might help. It’s not the best book (Refactoring by Martin Fowler us another), but it might help with planning the work. Quantifying cost and writing up a proposal then at least based on a defensible foundation.

👤 tacostakohashi
Rewriting never works, the canonical writeup on that is https://www.joelonsoftware.com/2000/04/06/things-you-should-...

You just need to tackle things incrementally, and communicate some honest, tough truths:

* If it took a couple of years to make the mess, it will probably take at least that long to clean up. Hopefully all the customers and business won while accumulating this tech debt was worth it.

* The organization needs to be ready for change. If people want to keep on operating the same way, rushing in changes, skipping unit tests, then things will keep on getting worse. People need to understand that continuing to operate like that will lead to more crashes/outages, less reliability, inability to win new business, etc.


👤 bvrmn
It seems you / your technical lead has no goal or vision of resulted code base without the debt. In this case it's really hard to catch up incoming changes and "make it prettier" is too vague.

👤 kiawe_fire
I will start off by saying that I have a messy legacy project that I work on and try to improve where I can, and I also would prefer to rewrite and start over. I haven't been fully successful at either approach yet myself, but I have made some progress, at least, so I can share some thoughts.

First, if they have "brought" you in and now expect you alone to fix things while they continue business as usual, that's a setup for failure all around. They need to "buy in" as much as you have, and everyone needs to establish some guidelines and expectations ahead of time.

Presumably, they have already bought in to the notion that things need to improve if you've been tasked with this at all, which is good (I don't always have this benefit). But it's not enough to bring somebody like yourself in, and then just continue business as usual.

So, first order of business - try to find a couple areas of the app that is a good combination of (1) relatively self-contained, (2) less of a moving target, and (3) able to provide visible gains when improved.

You might not be able to hit all 3 points, but find a good balance that gives a good bang for the buck.

For example, if one of your problems is data acquisition is too tightly coupled with view code, that might be a huge problem spread all over the place. So, find a subset of the problem -- something that gets used frequently (maybe, user login status? user permissions?) but is changed less frequently relative to other things.

Once you have a few suggestions, work with the team to agree upon ONE area. Take a little time to plan out how you want to improve it and why, and then propose your solution to the rest of the team.

With that done, get everyone to agree -- this one piece shouldn't be changed during your first "sprint" on this item without your involvement in guiding its direction.

I would suggest regularly updating the team on your progress and letting them in on any decisions you make along the way. The more they can be involved and help, the better.

The end goal is to end up with something that everyone has a little bit of ownership in, AND something with visible improvements such that the rest of the team will want to continue working with it "the right way" rather than piling on top "the old way".

Once done, try to find another feature and work it out the same way. In time, hopefully more developers will be more "sold" on newer patterns for development that you help establish, and will be more inclined to follow them when adding new code.

If this approach can't work for refactoring code, something similar can happen with a rewrite.

But there are two unfortunate problems that I continue to run into and don't know if they can be overcome.

1. If management insists you can work a miracle without the rest of the team needing to modify behavior, work alongside you, or include you in prioritizing or estimating new features, then the whole task is unrealistic.

2. If the developers working on the project are hostile to your efforts, have no desire to modify their practices and learn new patterns, or continually and stubbornly resort to old habits, then you will be fighting an uphill battle, even if you were to hand them a newly rewritten app.