“Software design is just theory.”
“Design patterns are too academic.”
“Writing code is the only way to become a better programmer.”
“Just ship it.”
As a consultant, I visit different clients throughout Europe. Some of them hire me for help with greenfield projects. Some others want my help with legacy projects, that they have been working on for typically 4-6 years. They are in different domains, with completely different codebases, but they also share many of the same problems. Progress is slow, they are spending 80% of their time on bug fixing, and each fix seems to create two new regressions. Some of them use popular open source frameworks, others use their own frameworks.
Early on in my career, I hated working with legacy just as much as everyone else. We work in an industry that is getting better at shipping large amounts of legacy at an ever increasing pace. We have created outsourcing farms, that produce legacy at the speed of typing. It’s legacy as a service. I felt I had to make a choice: get out, or get better. When you get better at working with legacy, you start enjoying it more. When you enjoy it more, you get better. You get the picture.
The 4-6 years is no coincidence: that’s when they start feeling the pain of every design decision that they made or didn’t make. Everything is coupled; moving one part causes a collapse in everything else. The frameworks that once were convenient and fast to market, are now a hindrance that they cannot get rid of. The RAD features that once put stars in the eyes of the developers, are now cursed upon. The business wants to add new features and access new markets, but they can’t. Management doesn’t understand why the team, that was so fast at delivering anything they were asked, is now slow and reluctant. New recruits take six months or more before they are productive — if they even stay that long.
Software design has a slow feedback cycle. It takes a long time before your design starts biting you in the butt. Over the years, smarter people than myself have seen the same patterns and anti-patterns, and have built designs that worked or didn’t work. They thought about them, looked at them from every angle, discussed them with colleagues. They investigated them with all the methods at our disposal: observation, logical reasoning, experimentation. They wrote blogs, papers, and books about software and design. Their ideas are not “just theory”. It’s years of accumulated practice and insights. They work — often in many different contexts.
We’re lucky: we can build on top of their ideas. You may need to type some more lines of code, but typing is not the bottleneck. You may need to rebuild the same piece of code a couple of times, but surely that’s a better than debugging. Sometimes, you need to over-design it, then take a step back, to understand how much design is just enough. You’ll need to learn a lot. For the rest of your career. You can’t accumulate all that knowledge just by writing some code every day. Read books, discuss them with others, read other people’s code, experiment, draw on a whiteboard, or take a walk and just think.
Learning is the bottleneck, and always will be.