Fresh from Tom Gilb’s “Advanced Agile Practices” presentation, I give you Dave Rico’s 14 pitfalls of agile methods:
If you look closely at the list, the entries don’t just apply to attempts at agilization. They are daunting challenges for any aspiring corpo change agent who wishes to make a sweeping change to “the way we develop products“.
The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise. — Edsger Dijkstra
With Edsger’s delicious quote in mind, let’s explore seven levels of abstraction that can be used to reason about big, distributed, systems:
At level zero, we have the finest grained, most concrete unit of design, a single puny line of “source code“. At level seven, we have the coarsest grained, most abstract unit of design, the mysterious and scary “system” level. A line of code is simple to reason about, but a “system” is not. Just when you think you understand what a system does, BAM! It exhibits some weird, perhaps dangerous, behavior that is counter-intuitive and totally unexpected – especially when humans are the key processing “nodes” in the beast.
Here are some questions to ponder regarding the seven level stack: Given that you’re hired to build a big, distributed system, at what level would you start your development effort? Would you start immediately coding up classes using the much revered TDD “best practice” and let all the upper levels of abstraction serendipitously “emerge”? Relatively speaking, how much time “up front” should you spend specifying, designing, recording, communicating the structures and behaviors of the top 3 levels of the stack? Again, relatively speaking, how much time should be allocated to the unit, integration, functional, and system levels of testing?
If ur customer *requires* formal waterfall events like “Sys Reqs Review”, “Prelim Design Review”, “Critical Design Review”, gotta do them.
— Tony DaSilva (@Bulldozer0) March 30, 2014
The customers of all the big government-financed sensor system programs I’ve ever worked on have required the aforementioned, waterfall, dog-and-pony shows as part of their well-entrenched acquisition process. Even prior to commencing a waterfall death march, as part of the pre-win bidding process, customers also (still) require contractors to provide detailed schedule and cost commitments in their proposal submissions – right down to the CSCI level of granularity.
If you think it’s tough to get your internal executive customers to wholeheartedly embrace an “agile adoption” or “no estimates” initiative, try to wrap your mind around the cosmic difficulty of doing the same to a large, fragmented, distributed authority, external acquisition machine whose cogs are fine-tuned to: cover their ass, defend their turf, and doggedly fight to keep the extant process that justifies their worth in place. Good luck with that.
I was going through some old project stuff and stumbled upon the chart below. I developed it back when I was the software lead of a nine person sub-team on an embedded system product development effort:
Putting all those indecipherable acronyms adorning the chart aside, note that the project was performed in 2004 – a mere 3 years after the famous “Agile Manifesto” was hatched. I can’t remember if I knew about (or read) the manifesto at the time, but I do know that Tom Gilb’s “Evo“ and Barry Boehm’s “Spiral“ processes had radically changed my worldview of software development. Specifically, the (now-obvious) concept of incremental development and delivery rang my bell as the best way to mitigate risk on challenging, software-intensive, projects.
As the chart illustrates, the actual hand-off of each of the seven builds (to the system integration test team) was pretty much dead nuts right on target. Despite the fact that the project front end (requirements definition and software design) was managed as a “waterfall” endeavor, the targets were met. Thus, I’m led to believe the following trivial trivia:
Not all agile projects succeed and not all waterfall projects fail.
Check out this slide I plucked from a pitch that will remain unnamed:
Notice the note under the waterfall diagram. Now, let’s look at the original, “unadapted” version and accompanying quote from Winston W. Royce’s classic 1970 paper:
Notice that Mr. Royce clearly noted in his paper that the sequential, never-look-back, waterfall process is a stone cold loser. Next, let’s look at another diagram from Mr. Royce’s paper; one that no fragilista ever mentions or shows:
OMG! An iterative waterfall with feedback loops? WTF!
Finally, let’s look at BD00′s syntegrated version of the agile, lower half of our consultant’s diagram and the iterative waterfall diagram from Mr. Royce’s paper:
Comparing the agile and “chunked“, iterative, waterfall models shows that, taken in the right context, they’re not that different…. no?
Rewritten in “old school” terminology, the five Scrum process events can be expressed as follows:
- Sprint Planning = Requirements definition and capture
- Sprint = Requirements analysis, design, coding, unit testing, integration testing, code review
- Daily Stand Up = Daily status meeting
- Sprint Review = Post-mortem
- Sprint Retrospective = Continuous process improvement
So, someone with an intentionally warped mind like BD00 may interpret a series of Scrum sprints as nothing more than a series of camouflaged Mini-Waterfalls (MW).
But ya know what? Executing a project as a series of MWs may be a good thing – as long as an arbitrary, fixed-size, time-box is not imposed on the team. After all, since everything else is allowed to dynamically change during a Scrum project, why not the size of the Sprint too?
Instead of estimating what features can be done in the next 30 days, why not simply estimate how many days will be needed to complete the set of features that marks the transition into the next MW? If, during the MW, it is learned that the goal won’t be achieved, then in addition to cancelling the MW outright, two other options can be contemplated:
- Extend the length of the MW
- Postpone the completion of one or more of the features currently being worked on
I’m not a fan of “emergent global architecture“, but I AM a fan of “emergent local design“. To mitigate downstream technical and financial risk, I believe that one has to generate and formally document an architecture at a high level of abstraction before starting to write code. To do otherwise would be irresponsible.
The figure below shows a portion of an initial “local” design that I plucked out of a more “global” architectural design. When I started coding and unit testing the cluster of classes in the snippet, I “discovered” that the structure wasn’t going work out. The API of the architectural framework within which the class cluster runs wouldn’t allow it to work without some major, internal, restructuring and retesting of the framework itself.
After wrestling with the dilemma for a bit, the following workable local design emerged out of the learning acquired via several wretched attempts to make the original design work. Of course, I had to throw away a bunch of previously written skeletal product and test code, but that’s life. Now I’m back on track and moving forward again. W00t!
Since Martin Fowler works there, I thought ThoughtWorks Inc. must be great. However, after watching two of his fellow ThoughtWorkers give a talk titled “From Agility To Anti-Fragility“, I’m having second thoughts. The video was a relatively lame attempt to jam-fit Nassim Taleb’s authentic ideas on anti-fragility into the software development process. Expectedly, near the end of the talk the presenters introduced their “new” process for making your borg anti-fragile: “Continuous Delivery/Discovery/Design“. Lookie here, it even has a superscript in its title:
Having read Mr. Taleb’s four fascinating books, the one hour and twenty-six minute talk was essentially a synopsis of his latest book, “Anti-Fragile“. That was the good part. The ThoughtWorkers’ attempts to concoct techniques that supposedly add anti-fragility to the software development process introduced nothing new. They simply interlaced a few crummy slides with well-known agile practices (small teams, no specialists, short increments, co-located teams, etc) with the good slides explaining optionality, black/grey swans, convexity vs concavity, hormesis, and levels of randomness.
Having recently watched a newer incarnation of Barbara Liskov‘s terrific Turing award acceptance speech on InfoQ.com, “The Power Of Abstraction“, I started doodling on my visio canvas to see where it would take me. Somehow, I wanted to explore how the use of abstraction imbues power to its wielders.
The figure below attempts to represent 3 different software designs that can result from the analysis of a given set of requirements (how the requirements came to be “given” in the first place is a whole ‘nother issue).
On the left, we have a seven class solution candidate (C1….. C7 ) organized as three layers of abstraction. On the right, we have a three class flat solution (FC1, FC2, FC3) that implements the same functionality (e.g. FC1 encapsulates the functionality of C1 + C4 + C7). For dramatic contrast, we have a fugly, single-class, monolith in the middle with all the solution functionality entombed within the MC1 class sarcophagus.
So, what advantage, if any, does the three tier, abstract design give stakeholders over the two, flat, down-to-earth designs? Depending on the requirements specifics, it may offer up no advantage and might actually be the worst candidate in terms of code-ability, understandability, and maintainability. There are more “parts” and more inter-part interfaces. It may be overkill to transform the requirements into 3 layers of abstraction before (or during?) coding.
However, as a system to be coded gets larger and more complex, the intelligent use of abstract vertical layering and horizontally balancing can speed up system development and decrease maintenance costs via increased readability and understandability from multiple viewing angles. For large systems, conceptual “chunking“, both vertically in the form of layering and horizontally in the form of balancing is a winning strategy; especially when coupled with Miller’s magic number 7 (no more than 7 +/- 2 abstract elements within a given layer and no more than 7 +/- 2 abstract layers in the stack). Relatively speaking, the smaller, bounded parts can be doled out to team members more easily and integration will be less painful.
Note that doing some just-enough “pre-planning” in terms of layering/balancing the system’s structure/behavior seems to fly in the face of TDD – where you sprinkle a bunch of user stories from the backlog onto a group of programmers and have them start writing tests so that the design can miraculously emerge. But, as the saying goes: “whatever floats your boat“.
When I started this blog four years ago, I had to decide whether to publish as an anonymous coward or to use my real name. I struggled with the decision for a bit because I knew I was going to write frequently, real frequently, about dysfunctional management and institutional behaviors that I’ve both experienced and (even more so) read about over the years. In addition, since I’m a high energy, passionate animal who doesn’t hold much back and at times finds it hard to compromise, I knew that much of my content was going be highly caustic and offensive.
Out of fear of repercussions, I decided to start writing incognito… until a dear friend brought up the perplexing issue again. After rethinking the situation, I resolved to let it all hang out. I gingerly hoisted my name up on my “About me” page. Never say never, but I didn’t (and still don’t) care about climbing any corpo ladder or presenting the squeaky clean image that all main stream “leadership” books tout as necessary to “get ahead“. I have some hairy warts and barnacles growing on my brain and, hell, I choose to expose them.
So, if I don’t want to get ahead by movin’ on up, then WTF does BD00 want? I want to keep ruining drill bits while I blast away at the impenetrable bedrock that entombs the holy grail of effective software development. I like going deep, deep, deep down into the unexplored corners of programming (in C++, of course), design, architecture, requirements, and the squishy realm of team-based software development processes. These closely-coupled topics excite me because there seems to be no bottom, no final “truths“, no end to life-long learning in any of them. It’s what I was meant to do.