When I say “speed up the build” what I mean is create a build environment that gives the results not in three hours, but in three seconds.
In order to do that you have to understand what your dependencies are. Very often that process helps developers see whether their architecture is good.
My consulting clients expect me to give results quickly, so I’ve learned a whole lot of techniques to create value fast. I often give suggestions on how they should best spend their effort, so I spend a fair amount of time looking at their code. The build will tell me whether or not they have a good architecture.
I have a client that requires 24 gigs on every developer’s machine, because even if you change the spelling of one little word of a message box you have to rebuild the entire enterprise system; nothing is hidden from anything else. And they had a brilliant architecture. The only problem was that the architecture was unencapsulated. A developer thought, I’m not going to use this API. It’s just going to change some data in a database. I’ll do it myself.
Because these developers broke the rules and there is no enforcement, everything became sprawled out. The result is 24 gigs on every machine to do a build.
But hey, memory is cheap. Just throw more hardware at the problem!
That may be the path of least resistance, but they now suffer a three-week release cycle—it takes them three weeks to validate that a release candidate is releasable with even the smallest change because they have to manually retest everything. And they want to go to a two-week iteration. If you do the math, it doesn’t actually work, so they have to rewrite everything.
Let me repeat that: They have to rewrite everything.
There are very few examples where you have to actually rewrite the entire system, but they’re there, and in this case it was because the behavior and the data have both been messed with at the same time. And, by the way, they’re running nearly a billion dollars’ worth of business every year, so this is not a small company. They struggled to transition all of their customers to the new system. They’re in an incredibly bad situation.
Software developers don’t have off-the-shelf components. We don’t build software by buying a part and just plugging that part in, but we can build in parts. If your car doesn’t start because the spark plugs aren’t firing but the spark plugs have been welded in, are wired to a dozen other components, and are also helping hold the engine in the engine compartment, it may be easier and more cost effective to just buy a new car than to change your spark plugs. This is what we call “dependencies.”
Good software development calls for building the parts and the whole together, but making each part as independent as possible.
We may find that there are still tendrils, things that connect things together, and those things should be a reflection of the real problem itself. There is a relationship between a customer and his or her street address, for instance. That’s a good kind of connection. There may be a connection between the zip code of the customer and the zip code of the shipper, but maybe that’s not the right kind of connection because if there’s only one shipper, they’ll have to deliver to any zip code. So understanding what can be decoupled—what can be separate from other elements—and what should be connected is of vital importance.
This makes total sense in the real world. We don’t even give a second thought to the idea that the spark plug is not permanently attached to the engine. In the virtual world, it’s not as obvious. In the virtual world, we don’t tend to think in terms of parts.
Now, I’m not striving for no coupling at all; I’m striving for an appropriate level of coupling. And that often depends on your perspective. Very often when you think about a problem in different ways, you can come up with better solutions. The same thing is true in software. So you want to have a variety of techniques to think about software problems in different ways, then run through your tool box of techniques until you find the one that clicks.
It’s the same thing a carpenter does. A carpenter has a whole bunch of tools on his tool belt, and a good carpenter knows when, how, and why to use each one. Software developers want to understand our tools and the scope of their usage in the same way other craftspeople, professionals, and artists do.