I recently took a trip with my wife to celebrate our 25th anniversary. This trip gave us time to reflect on our marriage and our relationship. We talked about what’s working and what we need to improve. From this background context, I started applying these ideas and discussions to the software I build.
The comparison may or may not be a good one. Our relationships with others are significantly more important than our work, but maybe there are some lessons we can learn from our relationships that will allow us to do better work. After all, we’re building our software for other people, and that work is another form of relationship.
A few months after I wrote those posts, I changed jobs and have now worked at a consulting company for two years. Instead of working on the same system for more than a decade, I’m now working on projects that last for a handful of months.
Even though the projects are short-lived, the systems I work on are not intended to be. They need the same care and attention for my short tenure as they would if I was working on them for many years.
What are the similarities between long-lived marriages and long-lived systems?
Almost anyone you ask will say that communication is the key to a good marriage. It’s important to talk with each other constantly to make sure you’re staying close and on the same page.
Communication is important in software design as well. It’s important to communicate with stakeholders to make sure the system is staying close to what they need.
Communication comes into play with the code as well. If the code doesn’t communicate well, it’s going to be difficult to make changes, especially as there is turnover among the developers.
When we work on our software, we need to make sure that we take the time to communicate with our team and stakeholders, and we also need to put in the effort to make our code clear and understandable, communicating our intent.
In a good marriage, it’s important to make sure that both partners’ needs are being met. It’s not necessarily my job to directly meet all of my wife’s needs. In fact, it’s not healthy for either of us for me to try. But I do need to make sure that those needs are being met somehow, even if all I can do is give her time and space for that to happen.
In a long-lived marriage, the couple will often be able to anticipate each others’ needs and meet them before they’re expressed. This can happen in big and small ways.
Similarly, we need to be sure that our systems are meeting the changing needs of our stakeholders. It may not be healthy for our systems to meet all of the needs of our stakeholders. In that case, we can work at integrating our system with another system that can meet the other needs.
If we put in the effort to deeply understand the domain we’re working in and the system we’re building, we too can get to the place where we’re anticipating needs before they’re expressed. If we can do that, our users and customers are going to love our software.
All relationships take work. We can’t just coast along and expect everything to turn out well. Because a marriage is one of the most important relationships in our lives, the stakes are really high. If we don’t work on our marriage, it will disintegrate and eventually end.
Similarly, if we want long-lived software, we need to put in the effort to maintain it well. Constant refactoring to improve the code, avoiding shortcuts that will hurt later, and putting in our best work every day will help. If we don’t do this, our system will crumble and we’ll be forced to rewrite it at great expense.
When problems arise in a marriage, they need to be addressed. Left alone, a problem will fester and cause many more problems.
A good way to address problems is to catch them while they’re small. They’re much easier to deal with this way, before anger and resentment build up over too many “little things” that have hung around for too long.
The same things happen with our software. Little problems arise, but we have a deadline to meet, so we ignore them. Pretty soon, all development comes to a halt because we can’t work around the problems any more.
I’ve found that I often trip over small issues that I identified earlier and chose not to address at the time.
On my current project, I’ve been keeping a list of refactoring ideas and small design smells that I’ve chosen not address immediately. It is amazing how many of those have come back up to get in the way of later development.
It’s important to be pragmatic. Sometimes, you don’t have enough information to address the issue right away. Maybe it’s the light cast by a future task that gives the insight that’s needed.
But sometimes, we’re just lazy or under pressure, so we don’t do what we know is right. We need to fight this urge and do better.
I definitely recommend experimenting with how aggressive you are in addressing these small issues when they arise. The list I’m keeping on my current project is definitely pushing me in the direction of refactoring sooner.
When we’re building software for others, it’s a good idea to try to build software that lasts. If our systems start crumbling, people get hurt and the resulting mess is expensive to recover from.
Reflect on your relationships. What factors make them good? What factors make them bad? What lessons can you apply to your life and your work based on that?