My team is in one of those little jams that seem to happen so frequently near the very end of development. We have a last minute requirement that requires us to treat a database entity a little bit differently depending on how the entity was created in the first place. What are we going to do you ask? Why, we’re going to put some sort of flag in the comments field for that database table. It gets better, in other cases that comments field may be storing some calculated information that we’re going to need for other purposes. Mystery meat. The inheritors of this system will curse our names for this one (except that it’s common in the system).
Ah, but here’s the rub. There is a field in the database that we could, and probably should, use to explicitly define the category of the entity. We’re not going to go down that path because the simple act of adding another value to the enumeration would involve too much work. The change management work plus the need to duplicate our changes in a completely separate environment and system to match our new category is simply too much work and risk for our timeframe.
These last minute changes do happen, and there’s a huge opportunity to screw up and make a mess for the next person — and since I’m such a fan of My Name Is Earl, karma has a way of making you be someone else’s “next guy.”
Fortunately, Jason Yip lays the answers all out for us in What would it take for last minute changes to be safe? To succeed over a length of time, your development ecosystem has to enable you to do the right thing in a timely manner, even at the last moment. Or put another way, you don’t want to tolerate artificial process restrictions or technical impediments that would discourage developers from doing the right thing for the sake of expediency. Granted, I’m intolerant of any kind of bureaucratic process, but nothing puts me to foaming at the mouth more than formal change management processes that make easy things difficult.* In our case, a fullblown Continuous Integration system (tests + automated deployments) plus a ruthless elimination of duplication between disparate systems would have made it much easier for us to do the right thing. More efficient configuration management practices for the database schema would remove the strong temptation to abuse a database structure.
Oh, and by the way, multiple transactional applications sharing a database is tantamount to sharing needles. In our case, changes in a Java server almost have to ripple over to a series of Objective C applications and vice versa.
Strategic versus Tactical Thinking
There’s a noticeable tension between tactical versus strategic thinking and planning. Tactical is “we’ve just got to get the project out the door.” It’s got its place, but you just can’t get away with purely tactical thinking (purely strategic thinking is a dangerous path to Analysis Paralysis and over design, but that’s not my problem at the moment). Creating technical debt just to get something done is an understandable risk, but it has to be weighed as a defrayed cost that *will* come due.
The hard part is looking for and recognizing strategic changes in technical direction that could enable more efficient execution of your tactical project work. Or look for the spots in your process or technology infrastructure that cause friction and inefficiency. The big challenge, and I’ve never seen any shop completely beat the problem, is to find a way to balance strategic improvements while maintaining the delivery of new functionality. I think the single most challenging task in all of software development is rescuing a challenged architecture while new development is in flight.
I hit the subject before in Balancing Technical Improvements versus New Business Features.
Big Ship, Little Rudder
I’ve been in a couple shops now that had severe problems with both technical debt and weak, disorganized processes. Inevitably there’s a feeling of lethargy and resignation that the problems just can’t get any better because they just look too daunting. Even if your means to make improvements are limited in comparison to the problems, you should still focus on creating a vision of the way you would like things to be. If you have ideas for improvement queued up, you might just find opportunities to slide the improvements in as you create new functionality.
The analogy I like to make is a big ship with a small rudder. If you want the ship to turn, you better start pulling on the rudder now. Besides, I think morale improves as long as there is some movement in the right direction. I don’t think anything saps the spirit of a development team more the belief that things are bad and the team is powerless to make it better.
Ok, I meandered quite a bit, and all I really wanted to do was use the cheesy title and big ship analogy.
* Somebody will think this is funny. Four years ago I left a position as a Systems Architect in a centralized architecture team to go join the Extreme Programming circus. To this day, I still think I was the strongest person on the team in terms of technology skill. For my replacement, they came very close to bringing in someone who had worked for 3 years in a completely hands off change management team. I think that’s probably a pretty good indication of how little they thought of the architect role.