On designing software you aren't working on
Here is Sean Goedecke arguing that you can't design software you aren't working on. He is basically correct. Here is an opinionated summary: "concrete factors dominate generic factors," in part because real systems have complexities that are hard to know about other than empirically. Moreover, the space of actually feasible changes is determined more by historical contingency than any high-level description of a system, so it takes boots-on-the-ground knowledge to know what can actually be done.
Besides simply recommending the piece--Goedecke is one of my favorite software writers--I want to add a couple takes:
- This is, in part, a severe condemnation of the state of software engineering. It's true that as systems get more complex, they get less predicable and more dominated by concrete factors. That's why it's really important not to make them too complex! Goedecke is terrifyingly accurate in describing the standard case, where various refactorings are impossible because of the way information is being passed through the system. What he doesn't say that at least some of these constraints are--at least in the median case--preventable, elementary failures of encapsulation.1
I would also emphasize that many refactorings are impossible not because information is not available in a subsystem (the case Goedecke emphasizes in his examples) but because information is already available in too many other subsystems, because of those encapsulation failures.
Encapsulation is still the most underrated idea in software, even though it's highly rated.
- One consequence of this argument is that studying the design of a system, in the traditional sense of "design" where you say a bit about what the subsystems are and how they interact, doesn't get you much. (If it doesn't tell you what changes are possible, can it really be teaching you much?) So, as I've argued, you often learn most about a system by first studying the structure and organization of the data, then learning how that data actually flows through the system. Studying design docs is often a zero-output failure mode.
In most organizations I've seen, I would trade every "design document" available for (i) a list of the important data stores, (ii) characteristic examples of data in those stores, and (iii) characteristic examples of processes that get data to, from, and between those stores.
So: keep fighting complexity, and keep reading Sean Goedecke.
"Elementary" does not mean "easy," and it certainly does not mean "I have an unblemished record of doing this brilliantly."↩