In my recent interview for Legacy Code Rocks, I talked about the arc of a developer. I feel like there is this trajectory that people that go on over their careers. It's the learning and growth path that developers tend to follow.
Relating to Software Design
Initially, I came up with this idea just from my observations about software design. In talking to Scott and Andrea I realized that it also applies to a developer's relationship to Legacy Code. I thought I'd throw this post together to help clarify my thoughts and also to see if it resonates with other developers, so please share your thoughts in the comments below.
Make It Work
When you first start out writing code, the biggest challenge is just making the computer do what you want. You start with learning loops, variables, and conditionals, but what you are really learning is how to use a computer to solve problems. The biggest challenge is just getting something that compiles and runs and spits out the right answer.
Make It Pretty
Eventually, you reach the point where you are pretty confident you can get the computer to do what you want. The next problem comes from one of the strengths of software, which is that its malleable. Someone asks you to make some changes to the code you've written and you pretty quickly realize that simple change is actually quite painful.
You start to realize that it's not just enough to make it work. How you make it work is also important. You start to study design patterns, frameworks, SOLID, clean code, etc.- all these things that promise to make your code more maintainable. You focus on making your code pretty.
At this point, the mistake a lot of developers make is that they become very dogmatic. They read about DRY, SOLID, and clean code and think that anything that doesn't 100% follow those rules is bad. They also start layering on more and more abstractions like it's some magic pixie dust that will solve all their problems.
Make it Simple
Eventually, you come to realize that the main enemy is complexity. All those layers of abstraction and adherence to arbitrary rules actually make your code more complex and harder to maintain. You find that no amount of documentation helps you to keep all the abstractions straight in your head. It becomes harder to reason about and therefore to change your code. You start to eschew a lot of the acronyms and get back to the most basic principle: KISS.
Relating to Legacy Code
There is also a 3 part arc that developers go through when it comes to relating to Legacy Code. I really didn't come up with this until I sat down to talk to Scott and Andrea. Since their podcast is all about Legacy Code, I started thinking about how I could relate these phases to a developer's relationship with Legacy Code. The 3 phases I came up with roughly correspond to the 3 phases I laid out above.
In the beginning, you are learning how to program. Most of the time, in beginning programming courses, you start with a blank slate, so-called greenfield projects. You are creating things from scratch, that you then throw away. You are not concerned about inheriting others' code or maintaining your own. You are simply trying to make it work.
Oh that. Ouch.
The first big shock is when you inherit someone else's code. It may break all the rules you learned in your classes. It may be undocumented and untested. Even if it is well-written and well-documented, it may still be a challenge just to figure out what is going on. That first encounter is almost always a painful experience.
At that point, most people react negatively. Lots of complaining ensues. The naive impulse is often just to throw everything away and rewrite it. You gloss over your complete lack of domain understanding and think, "Surely I can do it better with all my training." An arrogance starts to set in.
This is also the point where people get obsessed with preventing legacy code. You go out of your way to use the latest frameworks, design patterns, and acronyms to make sure that whoever inherits your code will never have to go through what you went through. You are going to write the cleanest, most DRY code possible.
Did I do that?
Then it happens. You inherit your own code. You come back to a project you wrote several years ago and you cringe. You look yourself in the mirror and say "Did I do that?" in your best Steve Urkel voice. You try to remember why you added so many layers of abstraction and why a function could only have 5 lines. You question everywhere you decided not to add a comment. You realize that despite your best efforts, you have now written legacy code.
It can still be a painful experience. The beauty of it is at that point you do realize the truth in the retrospective prime directive.
"Everyone is doing the best they can with the skills and knowledge they currently have."
You now have empathy for all those who came before you and will come after you. It may not make dealing with Legacy Code any more pleasant, but it at least gives you a grudging appreciation for it and the developers who create it - which is all of us, by the way.
What do you think?
Where are you at on the developer's arc? Have you noticed a similar progression? Have you arrived at valuing simplicity and having a begrudging appreciation for legacy code? Maybe you took a completely different path? If so, I'd love to hear about it. Let me know in the comments.