A Trace in the Sand
by Ruth Malan
The other day, Dana said "But, of course! All design is testing." That wasn't so obvious to me, but I hold Dana in (very) high regard, so I thought about it. Elaborating on the design characterization in the above trace, *...design
Design iterations (*...*) are messy, incomplete, and, while there is some "recursion" implied by that last bullet, it is not not not strictly hierarchical or "top-down." Where our design attention moves and what design medium we use (including, but not limited to, tests and code), is a judgment call (the extraordinary moment principle). Not only is there working at different scopes (sometimes "high level" and sometimes in the details, creating/evolving the "big picture" sometimes, coding units, building features/slices/services, etc., at others) as guided by judgment calls, but we also design across different facets, taking different (cross-cutting) concerns into account, and taking these different dimensions into consideration separately, sometimes, and together, sometimes. Accommodating for our (un)bounded (ir)rationality, for novelty and complexity, for multiple perspectives, and more.
And part of the design loop is testing -- ascertaining as appropriate to the design stage, if the design is on the right track [iterating between "right system" (fit to context and to purpose) and "built right," as there are trade-offs between what we are building and how it is built that ripple across not just what it is but how it works, and what it costs, and what the challenges are, and such]. That is, we're not simply elaborating the design. We're uncovering and resolving design trade-offs, assessing how we're doing against complexly interacting desired outcomes of various stakeholders, even as those outcomes come into clearer focus and potentially shift. We're learning -- about the context)s) into which the system will fit, what the system needs to be, and how best to accomplish that. So we may back-track, try different approaches. What makes it a design "loop" -- and one that may result in backtracking -- is the "testing," the probing for how we're doing so far, exposing our design to scrutiny and improvement. The style of testing will depend on what we have to test. If it's just a sketch prototype, the nature of our testing is rather different than if we have incremental builds of an evolving system. If our design process is to be responsive to finding things out, we're testing. Testing -- one could say challenging -- our ideas of what is needed. Testing our ideas of how best to create what's needed, solving the problems and addressing the inherent challenges and testing how well we did that.
We design to get more the outcomes we want, which has implicit in it the notion that it is not gobsmack easy connect-the-lego-blocks-into-a-simple-prefab-structure kind of thing. So we design to figure out the outcomes as well as how to achieve them, and we improve the design to get more what we want.
It is built into the very notion of design that we test. We probe, we explore, we verify -- we test to improve, not simply to prove or establish that we did it "right" and are getting expected results. And we may leave a scaffolding of tests around the design frames (at different scopes), so we can verify that changes within a frame still work within the commitments of the frame. (Alternately, they form a "regression bedrock.")
"Sweetness," as coined by Michael Feathers, is "when a single mechanism satisfies many different needs in an elegant way." Unit testing in the TDD mode has that kind of sweetness. We design a unit that has intentionality and commitments and a boundary (what's in/responsibilities and interaction surface/I/F and protocol; and we may be thinking in terms of boundary conditions and containment of side-effects, etc.), and our design thinking there does double duty, establishing how we will test that unit. And thinking about testing that chunk of intentionality or design commitment, helps us improve the design, so that it is more than just a means to establish that the code is delivering to its commitments (once first built, and as it is evolved and refactored).
But sketch-prototyping does (more than) double duty (i.e., has sweetness) too. Models that lead to simulations, too. Because outcomes arise emergently from interactions and collaborations among various "units," and we don't have all the units a priori (even when we're evolving a system, we don't have the new endpoint, upfront).
We model to think, to create a shared thoughtspace where we can think together about the form and shape and flow of things, the how-it-works things both before we have code and when the very muchness of the code obfuscates and it is all too much to hold in our head, and we need to think about interactions among, cross-cutting concerns, how things work together, and such. And models help persist our thinking -- informally sketched and preserved as digital photos we slap into the project memories "scrapbook"... or more formally, as models we tech up, if circumstance warrants the extra degree of ceremony and/or formality and/or blueprint-y precision. And they help us test our ideas -- in an exploratory way when they are just sketches, but also as simulations. They help us decide what to instrument, to make visible. If you need some nudging along the lines of models help us see, or notice, help orient us to observing::
Drawing is good training in the art of seeing. And sketch-modeling systems is good training in noticing the relationships between structure and function, noticing relationships that give rise to and boost or damp properties, and so forth.
At any rate, we design. We utilize abstractions at different design scopes and in different ways. We test to probe, to learn, to verify the efficacy of the abstractions under multiple simultaneous demands (for they deliver capabilities and qualities of our system). We evolve the design. We factor and refactor; we reify and elaborate. We test and evolve. We make trade-offs and judgment calls. We bring what we can to bear, to best enable our judgment, given the concerns we're dealing with. Sure. It's kind of messy. Kind of wicked. Kind of crucial! We test. That is we probe. We instrument. Variously. Software is a highly cognitive substance with which to build systems people and organizations depend upon. So. We design-test our way, with different mediums to support, enhance, stress and reveal flaws, etc., etc., in our thinking. We probe. We reason. We verify. Not using sketch-prototypes to do A/B field testing. Using judgment. Naturally! (Yessss! Judgment factors. And factors and refactors. But also tests. Informally. And more formally. As fits the extraordinary moment. ;-)
Uh. Now I have to test if that is what Dana meant... Hey I try. Some people call it failing, but I call it trying. I try. And I try. We have to try different things, from different angles, experiment our way to learning and figuring out what we want and an approach to getting it more the way we want it to be. And in this case, I want to learn. So I try. Try to understand. Try to get my understanding expressed, and tested for clarity and serviceability. And so forth. I try. Okay. I try.
Oh. And Tom Graves says I'm eminently quotable so I tried that too -- I quoted myself in a call-out. ;-) Smiles. Thanks Tom. And Gene. Hugs and skips of gratitude. You give all my hours of trying a rewarding moment of blissful recognition of peership on this shared flight on spaceship earth.
5/12/14: Thanks to Paul Harland for the conversation on this topic. It is nice to be taken seriously enough to have some discussion that furthers my ideas. Paul will no doubt see his influence in this trace, and I'm grateful -- thanks Pablo. :-)
5/20/14: Allowing that TDD pushes design, it is just one scope and frame of design.
While we're bringing babies back, let's bring back the notion that code is not the only design medium. Oh sure, code and tests have that beguiling "sweetness." But models have sweetness too. Not one or the other. Not BDUF. But let's allow that models help us push testing to broader scopes and earlier -- to test ideas. Sure. We have to loosen up our notion of testing, but we do so to allow ourselves the benefit of probes for direction, so we can test drive our strategy cheaply and quickly, before it is hard-cast in organization and code structures, with all their coupling -- intended and un, including to assumptions, explicit and im. Which is a nice segue to the next trace. ;-)
5/20/14: It occurs to me that those who thrust their preconceptions onto me, may think that my design loop (iterating between the *s in the 5/9/14 tracelet above) implies top-down. No no! Fractal and Emergent -- remember? And messy! At times. We seed with a notion of significant abstractions, and we factor and refactor, seek out abstractions and design mechanisms -- proactively, and with the benefit of hindsight. That is, we bring learning from past and peer projects. And we learn as we go. We try things out. Yadda.
Oh. You should read this:
Now you understand my traces. ;-)
Oh. And read, or reread, this: Fractal and Emergent. Yes, it is that good. How good? Worth giving your contact info to get, duh. Hey. Think short ebook, written by the awesome (trumpets please) moi and db. For just the price of your contact info. Heck, you'd have to give that if you paid with your credit card. But the fractal and emergent, strategy and architecture in tandem, etc., ideas are that important, and it's so, you know, wonderfully written. (cue more trumpets).
5/31/14: See also:
PS. I'm beginning to think "is dead" doesn't mean what
Since Conway's Law is in the air again, you might like to catch up on all the awesome I've written about it (smiles):
Tl;dr? Here are some highlighter quotes:
That statement is awesomely profound/has far-reaching implications. Just think about all the "360 degree view of the customer" and "single authoritative data source" efforts we've had to go through. Again. And again. Because the organizational silos around the different lines of business are apparent to incredulous customers confounded by the lack of integration (of information and products) across services from the "same" company... Organizational divides and "silos", from teams to divisions or lines of business, show up in what we provision, from services or products to solutions or systems-of-systems, in the ecosystem.
Michael Feathers used the notion of echoes to talk about how organizational and process influences show up in the code.
The point that I was making there, is that we only get a very partial view of the history.
Image right: from mfeathers talk "Conway's Law and You" (insightful; Michael structures his talks with implications and guidance)
So, we can sniff out the echoes, do some archeology, but are they enough to understand the influences, direct and indirect, intended or un, that shaped the code?
[Opportunity for] Symbiosis:
Allan Kelly's Conways Law & Continuous Delivery slideset points to his contributions to the industry understanding of Conway's Law and it's implications, both direct and in dual and corollary form.
And here are some thoughts scooped up from traces over the years:
That is, there is a relationship between the architecture of the organization (and its communication flows) and the architecture of the system (and its boundaries and flows). We need to take this into account, to reap synergies rather than doing the harder thing, trying to "swim against the current." Oh yeah, and this:
Abatis? See points mfeathers makes about interfaces between teams.
Refactoring is the corollary to piecemeal growth, allowing entropy containment. But we have to refactor the organization too? If it would subvert the system (re)design and evolution.
5/7/14: Michael Feathers used the tree rings metaphor in his "process echoes" and "symbiosis" talks. So my "what I'm paying attention to shapes what I perceive and pay attention to" mind noted:
I should return to that Software Visualization work -- I think there is a lovely book in it. But first, sigh, that neverending Architecture story. ;-)
5/9/14: Two great additions to the Conway's Law insight crucible:
5/24/14: Very nice application of Conway's Law-derived insights to microservices and "granularity" decisions, given organizational considerations by Gene Hughson (my italics):
Great add to the symbiosis conversation, and tie-in to microservices.
Hey, so I snipped another nice add to the conversation:
6/1/14: The question of self-organizing teams is interesting, in this context.... Tangentially related (well, it just touches at the point of self-organizing, so this seems like a good placeholder for it):
7/3/14: Playing well together:
As I pointed out early in the above trace, integrating across organizational divides is a challenge and... when left to happy accident, may well have all the smack of accident rather than design -- as in, designed to get more what we want, looking for consequences so we get less unintended side-effecting from being system-blind.
8/1/14: Collection of observations on Conway's Law (via Rachel Davies):
10/7/14: A few more links (because... you're that curious/investigative):
And the awesome:
which I quoted in my Architecture of Responsibility trace, which should have you hightailing it over to my Conceptual Architecture write-up.
I responded with a pointer to this trace because "you always ship your organization" (feathers) and the subsequent paragraph is one elaboration. And added that I have my own hypotheses about how Twitter is organizaed, given, for example, how DM content is staged and delivered up so differently across browsers/devices. (But I didn't get a response and then I felt like it was rude to barge in on a side convo even if it showed up in my stream because I follow both. So I deleted my tweet so as not to intrude longer on a stranger's interaction line. Twitter is hard. I'm not socially adept, so I don't know what's impolite...)
11/25/15: And this is great:
Also, from the man himself:
And if you want to see what Mel Conway has been up to more recently (hint: Worry Dream/Bret Victor and visual thinking comes to mind):
Yesterday I learned:
I also write at:
- Bredemeyer Resources for Architects