My team and I took over a medium sized codebase over a year ago when the previous tech lead left the company. Originating from the lack of man power I fear we favored pragmatic solutions over best practices a little too much.
Now, I have to deal with a constant decline in code quality and some kind of organic growth of day-to-day processes. I regret that when asked for code conventions a year ago I basically gave common sense as the only rule. Soon I had programmers using different syntactic styles and failing to see the difficulties this induces in a merge process. Another example is my push for database migration scripts. I tried to incorporate Flyway into our process but after only a week I was quickly overruled by my boss. Even despite me warning them about the upcoming mandatory use of database migration scripts and providing them with as many clues, hints and tools to mitigate the problem of not starting applications because of missing or failing migrations they decided that it would be best do complain to my boss about them not being able to do their work. I forcefully disabled Flyway again and we now live with migration steps in arbitrary named SQL files on a network share that you have to remember to apply to the respective database at the right time.
One problem in our process was that we never did formal code reviews. So a lot of hacks went under the radar and into the code base without someone noticing on time. Nowadays I tend to read checkins of my team mates when there is time (that’s not often the case) but there is no automatic process to prevent unwanted changes. It is up to me to go to the developer in question and try to ease them into acknowledging why their code is bad. I thought to introduce lint-like tools like FindBugs and Checkstyle but I fear I would face the same psychological problems like I did with the database migrations. After all I would make their jobs harder for them and I can understand why this might lead to misunderstandings.
So my question is: How can I go about improving our process and our code quality in an environment where getting the job done is valued much higher than doing it right?
5
Let me guess…now you have a team of developers mired in daily production support because the stream of issues coming in is endless and no one gets to work on more strategic things?
I’ll be curious to see what kinds of answers you get, but without being too pessimistic here I think you’re in for a heck of an uphill battle, mainly because my first bit of advice would be to get management on your side, and these quotes make me think that’s going to be difficult:
I was quickly overruled by my boss
and
an environment where getting the job done is valued much higher than
doing it right
I like to refer to this as the decision-consequence gap. The people making the decisions do not have to suffer the consequences of the decision. If the decision is bad, the fallout is often someone else’s problem. If the decision is good, or was bad and the hard work of others made it look good, then of course the decision maker takes credit.
I’m not busting on you here, these problems are a sadly systemic issue I see in most corporate IT shops and the corporate world at large. It’s what causes them to narrowly put delivery date before quality in every project. And of course they’ll do that because they are judged by their superiors on date first; as none of them have to live with the software’s deficiencies, quality doesn’t really matter to them.
Ideal Solution
Anyway, the “happy path” scenario is that you get management to agree to:
- Halt new feature development while you make a focused effort to repair and refactor major deficiencies in the code.
- While they’re at it, they empower you to release anyone from the team that isn’t smart enough to recognize the value of best practices and doesn’t want to change their hack-style of coding. Getting rid of crappy developers is probably even more valuable to the team than the refactoring itself; good developers will find ways to refactor as they go, naturally improving things over time.
Management in this scenario recognizes that the leaks in the boat must be repaired or much time and money will be lost in paying for a team that is stuck churning through tactical issues (user hand-holding, data fixes, rote tasks, and other assorted diaper changes) rather than strategic (new features to enable user efficiency, improve quality of customer-facing output, and make possible new streams of revenue).
Pragmatic Solution
Look, we know the above theoretical ideal is unlikely to happen based on what you’ve already told us. That leaves you and your team to find ways to handle this on your own.
- Establish the standards you need. You mentioned it in your post; get them published and get the team to understand the value and begin implementing for all future work. If you can keep the issues load stable even as the code grows because the new features don’t add more problems, then that’s a small but laudable victory against tough circumstances.
- Refactoring is likely one of your best approaches. Every time you have to go in for a fix, take advantage of the opportunity to also clean up that script and improve it some. If you can’t get management to support a directed repair effort then evolve the code slowly; you might have to engage some overtime but some improvement is better than none. The problem here is that it works for individual scripts, but less well for system-wide changes that need to happen simultaneously in large numbers. But you may be able to blend in some larger changes if you do get some new feature request; you must be tactful though. I once got my hand slapped by a project manager that thought I was actually greenlighting unapproved work (I was not, I was implementing changes that would fix a part of the system and in turn enable the new requested feature and was thus a material part of the project).
- Make staffing changes? I don’t want to speak out of turn because I don’t know the full story behind your team, but it sounds like they are quite comfortable with sloppy quick fixes and don’t appreciate best practices like code review. If you’ve identified people that are creating more problems than they solve, perhaps they can be put somewhere else. This is a tough one because these days management doesn’t like firing people for incompetence because that’s politically incorrect; they only fire people for hurting someone’s feelings. But I mention this because it is a factor; poor developers compromise the rest of the team’s efforts. You will waste many hours trying to convince them to improve, and any work they manage to get into production will create more support.
Really Pragmatic Solution
A lot of the folks on the stackexchange sites are smart people that are also impatient and are quick to say, “Just leave, it’s obvious your shop isn’t going to get any better.”
I’d agree with them if you really feel it’s not going to get better. But obviously you have to be careful because at least in my experience, you have a chance of ending up somewhere that has the same problems.
Also, this site’s sidebar lists several similar questions you could look into for advice.
5
You are never going to get around technical debt, it’s a commercial necessity. Even if you are lucky enough to have bosses who get it, they’ll still say I need it yesterday, or that the risk of reworking the legacy code to improve it for what they consider to be weird arcane propeller head aesthetics, isn’t acceptable.
Even if you were CIO, you’d have a herculean task to impose best practices on your colleagues, and that’s even if you could agree that they were “best”
The best approach, especially if you are low down in the food chain, is self defense.
Get the idea across if they do that like this, it will make their job easier not yours.
Don’t go all esoteric on them, good naming practice (not some Hungarian notation thing) and common architecture can alleviate all sorts of comprehension issues.
Something as simple as the routine that displays the entity on the form is always called DisplaySomeEntityName
Start simple don’t try to build and an entire hierarchy of good practice before you do anything. Build it together organically.
It might be just an impression I’m getting, but a key point is to make Code Reviews are time where you can help each other not criticize each other.
It’s not you’ve done it wrong.
It’s I don’t understand what you’ve done.
So instead of you reviewing their code, get them to review yours.
If it’s a good habit and it makes things easier, they’ll start doing it.
Never know you might be doing it wrong, I’m a bit of a nut about this sort of thing, but I’ve been pulled up more than a few times by my code only being comprehensible to me, just after I wrote it….
2