In an attempt to gain an understanding of the software design he was carrying around in his head, I sat down with a colleague and started talking face to face with him. To facilitate the conversation, I started sketching my emergent understanding of his design in my notebook. As you can see, by the time we finished talking, 20 minutes later, I ran out of ink and I wasn’t much better off than before we started the conversation:
If I had a five year old son, I would proudly magnetize my sketch on the fridge right next to his drawings.
To illustrate the difference between analytical thinking and systems thinking (which some people think are identical), Jamshid Gharajedaghi presents these two figures in his wonderful book: “Systems Thinking: Managing Chaos and Complexity“.
Anyone who has been through high school has been exposed to equations of the type on the left. To discover the impact of one variable, say x1, on the system output, y, you simply vary its value while keeping the values of the other (so-called) independent variables fixed. But what about equations of the type on the right? Every time you attempt to vary the value of one variable to discover its effect on system behavior, you unwittingly “disturb” the values of each of the other variables… which in turn disturbs the variable you’re trying to directly control… which in turn disturbs the set of variables yet again… ad infinitum. It’s called the law of unintended consequences.
Nice and tidy equations of the type on the left are applicable to, and only to, problem modeling in the natural sciences in which the players are time, energy, and mindless chunks of matter. Intractable sets of equations of the type on the right, unsolvable messes in which every variable is correlated which every other variable, are applicable to socio-technical systems where the most influential players have minds of their own. System thinkers focus on the coupling and dynamic interactions between the variables in the system to understand emergent behaviors. Analytical thinkers assume away (either consciously or unconsciously) the nasty, non-linear, inter-variable couplings and thus form an erroneous understanding of the underlying causes of system behavior. Welcome to the guild of business management.
The following C++14 code fragment represents a general message layout along with a specific instantiation of that message:
Side note: Why won’t a C++98/03 compiler accept the above code?
Assume that we are “required” to send thousands of these X-Y position messages per second between two computers over a finite bandwidth communication link:
There are many ways we can convert the representation of the message in memory into a serial stream of bytes for transmittal over the communication link, but let’s compare a simple binary representation against an XML equivalent:
The tradeoff is simple: human readability for performance. Even though the XML version is self-describing and readable to a human being, it is 6.5 times larger than the tight, fixed-size, binary format. In addition, the source code required to serialize/deserialize (i.e. marshal/unmarshal) the XML version is computationally denser than the code to implement the same functionality for the fixed-size, binary representation. In the software industry, this tradeoff is affectionately known as “the angle bracket tax” that must be payed for using XML in the critical paths of your system.
If your system requires high rates of throughput and low end-to-end latency for streaming data over a network, you may have no choice but to use a binary format to send/receive messages. After all, what good is it to have human readable messages if the system doesn’t work due to overflowing queues and lost messages?
In his terrific “Effective architecture sketches” slide deck, Simon Brown rightly states that you don’t need UML to sketch up your software architecture. However, if you don’t, you need to consider documenting the documentation:
The utility of using a standard like UML is that you don’t have to spend any time on all the arcane subtleties of meta-documentation. And if you’re choosing to bypass the UML, you’re probably not going to spend much time, if any, doing meta-documentation to clarify your architecture decisions. After all, doing less documentation, let alone writing documentation about the documentation, is why you eschewed UML in the first place.
So, good luck in unambiguously communicating the software architecture to your stakeholders; especially those poor souls who will be trying to build the beast with you.
At its core, process agility is all about continuous learning, fast feedback loops, and fluid changeability. Unlike pre-agile methods (and even some currently purported agile methods), which assume that people are forward-marching automatons who “better not make mistakes” and must defend the fort against all external forces of change, process agility accommodates the mental limitations and fallibility of REAL human beings.
Having said that, how agile do you think a process which includes a sign-off list like this is:
Imagine that whatever has been “approved” by a ceremonial sheet like this is post-facto found to be laced with errors, inconsistencies, and ambiguities due to natural human fallibility. How likely do you think that finders-of-mistakes will publicly point them out, demand a production line stoppage to fix the turds, and suggest that the director-manager-lead approval gauntlet be traversed again? Conversely, how likely do you think that finders-of-mistakes will say “f*ck-it!“, keep their mouths shut, and keep goose-stepping forward with the herd.
Fear not, dear reader. BD00 has a simple and clean solution to the director-manager-lead approval gauntlet problem. Collapse the list of approvers down to one – the only one that matters:
Please submit your plans for BD00 approval in the comments section. As his executive assistant, I can assure you that his stamp/no-stamp decision will be made pronto. However, don’t call us. We’ll call you.
Induction is the process of synthesizing a generalization from a set of particulars; a mental step up in abstraction from many-to-one.
Deduction is the process of decomposing one generalization into a set of particulars; a mental step down in abstraction from one to many.
A good personal software design process requires iterative execution of both types of sub-processes; with liberal doses of random reflection thrown into the timeline just to muck things up enough so that you can never fully retrace your steps. It’s pure alchemy!
When all is said and done, more is said then done. – Unknown
Savvy politicians and bureaucrats seem to always say the right thing, but they rarely back up their proclamations with effective action. In “Military’s focus on big systems is now killing us”, DARPA Director Arati Prabhaker states the patently obvious:
The Pentagon must break this monolithic, high-cost, slow-moving, inflexible approach that we have.
Well, duh! I’ve been hearing this rally cry from incoming and outgoing appointees for decades.
Yet another insightful DARPA director states:
The services have largely failed to take advantage of an emerging “software-defined world.” The result has been skyrocketing weapons costs.
Say what? “Sofware-Defined World“? I must have missed the debut of this newly minted jargon. The “Internet Of Things” and its pithy acronym, IoT, must be so yesterday. The “Software-Defined World“, SDW, must be so today. W00t!!
If you read the article carefully, you’ll see that the interviewees have no clue on how to solve the grandiose cost/schedule/quality problems posed by the currently entrenched, docu-centric, waterfall (SRR, PDR, CDR, Fab, Test, Deploy) acquisition process and, especially, the hordes of civil servants whose livelihoods depend on the acquisition system remaining “as is“. But BD00 does know how to solve it: Certified Scrum Master and Certified Product Owner training for all!