Going Backwards to Go Forwards
I worked on an interesting problem this week that might have looked like I was running around in circles if you just looked at my SVN commits.
The problem, and the eventual solution, reminded me of an important part of software development—of building anything really.
Sometimes you must tear it down!
No really, sometimes you build a structure only to tear it down the very next day.
It’s not a mistake. It is intentional and productive and if you are not doing it, you very well might be making a real mistake.
That is highly illogical
Imagine for a moment that you are tasked with the job of repairing the outside walls of a 2 story building.
There are of course many ways you could go about doing something like this.
- Use a ladder and just reach the part of the wall the ladder allows you to. Then move that ladder, repeating the process as needed to complete the repair to the entire wall.
- Try to lower yourself down from different windows to reach as much of the wall as possible.
- Tear down the entire building and rebuild the building and walls.
I am sure there are plenty of other methods besides what I listed here.
Yet, a very simple approach would be to build a scaffolding.
A scaffolding is basically a temporary construction used just to help repair or initially build a building which is built for the very purpose of eventually being torn down.
Software is different, we don’t contend with physics!
You are absolutely right!
We contend with a much more powerful force…
Conceptually anything you can create in software could be created without any kind of software scaffolding. Unfortunately though, the complexities of the logic of a system and our abilities as humans to only contain so much of it in our brains impose a very real limitation on our ability to even see what the final structure of a metaphysical thing like software should be.
So what am I saying here then?
I’m just saying that it sometimes helps to remember that you can temporarily change some code or design in a way that you know will not be permanent to get you to a place in the codebase where your head is above the clouds and you can look down and see the problem a little better.
Just like there are physical ways to repair a wall on a 2 story building that don’t involve wasting any materials by building something that will be torn down, there are ways to do build software without ever building scaffoldings, but in either case it is not the most efficient use of time or effort.
Don’t be afraid to take a blind hop of faith
Source control is awesome!
Source control lets us make changes to a code base, track those changes and revert them if needed.
Working on a code base without source control is like crawling into a small crevice in an underground cave that has just enough room to fit your shoulders—you are pretty sure you can go forward, but you don’t know if you can crawl back out.
But, with source control, it is like walking around a wide open cave charting your trail on a map as you go. You can get back to where you want to any time.
So as long as you have source control on your side, and especially if you are using a distributed source control where you can make local commits all day long, you don’t have to be afraid to step out on a software ledge and see where things go.
Oftentimes I will encounter some problem in code that I know needs to be fixed and I know what is wrong with it, but I just don’t know how to fix it.
When I encounter a problem like this, I will often have an idea of at least one step I could take that should take me in the direction I believe the code needs to go.
A real example
To give you a real example, I was working recently on some code that involved creating a lot for a product. (Think about the lot number you might see on a box of Aspirin that identifies what batch of ingredients it came from and what machine produced it when.)
Up to the point in which I had been working with my teammate on refactoring this code, there had only been only one way to produce the lots.
We were adding some code that would add an additional way to create the lots and the labels for those lots. We also knew that there would be more additional ways in the future that would need to be added.
Well, we knew we wanted to have a generic way of specifying how lots should be created and labeled, but we didn’t know what the code that would do that would look like.
We could have rewritten the entire lot handling code and made it generic, but it was quite complex code and that would be equivalent to tearing down a building to fix a wall.
It was apparent there were some parts of the existing code that were specific to the way that the current lots were being produced, so we knew those parts of the code had to be changed.
So what did we do?
We started with what we knew needed to be changed and what we thought would move us in the direction we wanted to go, and we built some structures to allow us to refactor those parts of the code, knowing that we would probably end up deleting those structures.
The scaffolds that we created allowed us to have a midway point in the long journey across the Pacific ocean of complexity in our refactor trip.
The point here is that we had to take a bit of hop blindly in a direction we thought things needed to go and part of that hop involved creating some scaffolding type structures to get that code to a place where it still worked and we could examine it again for the next refinement.
The final refinements ended up deleting those scaffolds and replacing them with a more elegant solution, but it is doubtful we would have been able to see the path to the elegant solution without building them in the first place.
Show me the code!?
You may wonder why I am talking about code in such an abstract way instead of just showing you a nice little “scaffold pattern” or a real code example.
I’m not going to show the code, because it isn’t relevant to my point and it is so situational that it would detract from what I am trying to say here.
The point is not what our problem or solution was, but how we got there.
There isn’t a “scaffolding” pattern that you can just apply to your code, rather it is a tool that you can use and shouldn’t be afraid to use in order to move your code forward to a better design. (To its happy place.)