Tuesday, May 30, 2006

Simple ain't Easy: Myths and Misunderstandings about Simplicity

Obviously not all of us have the same idea of what Simple or Simplicity actually mean, specifically in the context of system design (including software, and processes). Here are some common misunderstandings that I frequently encounter about the meaning of "simple design":
"Simple" is not the same thing as "easy to do/understand."

Sometimes something that is "simple" is easy to do or easy to understand. Whether or not it is easy, is often more closely related to how familiar or intuitive it is. Eventually, it may be quite simple to do or understand. But initial attempts to do or understand it may be anything but easy!

The simpler solution may require us to learn something new, and think about something in a way that hasn't occurred to us before. Closed-minds will often close-doors on new ideas (simple or otherwise) because they simply don't want to entertain changing their current views and beliefs.

"Simple design" is not the same thing as "simple to develop/deploy."

If it's simple from the get-go, then it may perhaps be simple to develop/deploy. If the solution is already in place, then making it simpler may involve changing a lot of minds/behaviors as well as a lot of the system, and both of those may be anything but easy to do (especially changing minds/behaviors).

"Simple" is not the same thing as "good enough!"

Put another way, Simplicity != Sufficiency. "Good enough" has more to do with whether something is sufficiently workable "for now" while still fostering subsequent improvement or refinement for later. That doesn't mean the deployed result is simple/simpler; it just means we may be better served by getting to that point in an incremental and evolutionary (emergent) fashion.

In order for that to be true however, it means that the partial/incremental solution must be easy to subsequently change in order to refine and improve!!!

If I install something that is incomplete with the intent of making it more complete, and if it is very hard/painful to change, then I may end-up with the current-state-of-affairs for a number of IT solutions and business-processes: short-sighted, insufficient solutions that the organization defends, and chooses to suffer and impose on others because they don't want to suffer the impact of the change that could bring about relief from the suffering they have become accustomed to living with.

"Simple" is not the same thing as "simplistic!"

A simplistic solution often does not work! One definition of "simplistic" might be the false appearance of simplicity. It's not enough to seem/appear simple. It also has to work (successfully) in order to actually be simple!

Many times someone will discard or exclude a suggestion because it introduces something additional or new into the current design, and they don't want to add anything more/new in the name of simplicity, but they may be being simplistic instead. If the new/added thing is a rightful part of the problem that needs to be solved, then its introduction is correcting an act of omission in the solution design that neglected something essential in the problem-domain.

Sometimes we exclude things that we don't want to see (in the name of simplicity) which are nonetheless a real-world element of the problem we need to solve. Dismissing them in the case where ignoring them has failed to solve the problem, is not simplicity; it is ignorance. It is okay to want something that is "stupidly simple," but not at the expense of being simply stupid!

If the result doesn't do what it's supposed to do when it's supposed to do it, it may seem simple, but, as Gerry Weinberg points out, it's likely that something crucial to the problem statement was omitted or misunderstood either in the design, or in the problem statement itself.

What is "simple" for one request may not be "simple" for the whole!

When faced with a single, seemingly simple request to enhance a system, the requestor may want the specific solution to be simple for their particular situation and perspective (this is sometimes called "point-based thinking"). But what usually needs to be simple is the resulting overall system. Making it simple from one view or situation may just compromise other parts (and stakeholders) of the system. That's not eliminating complexity; it's not even "sweeping it under the rug"; it's just sweeping it onto someone else's doorstep.

Note how a lot of these myths/misunderstandings are more about resistance to changing our thinking/behavior than about being simple.

The Agile Manifesto defines simplicity as "maximizing the amount of work not done." But I think that's a more accurate characterization of Lean than of simplicity.

Recently, I looked though a number of sources of information about what is the meaning of "simplicity" and what are its principles, and I came across a number of interesting resources:
After mulling-over all of those, I think it's fair to say that while "Simplicity" may be, well, "simple", truly understanding "simplicity" is in fact quite hard!
  • Simplicity involves being able to see the whole from a systems thinking perspective while at the same time being able to focus in on what is relevant and essential and how it impacts the rest of the system.
  • Sustainable simplicity often has to evolve or emerge on it's own from a set of simple guiding rules.
  • The opposite of simplicity is complexity (as opposed to "hard" or "difficult" or "time-consuming" or "labor-intensive")
  • In mathematics, simplicity is often "elegance" and is more than just the intersection of "what is necessary" and "what is sufficient"
  • In architecture, "simplicity" is often synonymous with "beauty"
  • Hiding complexity isn't the same as removing complexity.
  • Many of the tools we use to manage complexity in systems design may in fact add more/new objects to hide complexity or separate concerns
  • Minimizing dependencies throughout a system is more critical to simplicity than minimizing the number/types of objects
  • Occam's Razor does not in fact say that the "simpler explanation is better" ... it says that the explanation that makes the fewest assumptions and poses the fewest hypotheticals (i.e., minimizes the number of "given" and "unproven" conditions) is the most preferable because it is easier to comprehensively test in order to prove/disprove.

I think that true simplicity is about minimizing and managing overall complexity. Complexity in software design and development comes from the sheer size and complexity of the problem we are being asked to solve, and the richness and vastness of the interconnected maze of interactions within the system and between the system and its environment.
  • The overall complexity of the system is dominated far more by the interactions between the parts that makeup the whole than it is by the parts alone.
  • For any non-trivial system, simplicity often has less to do with the number and kind of different things involved and more to do with the number and kind of interdependencies between them.
So achieving simplicity is less about managing "parts" of "things" or individual point-solutions, and is more about managing rules and relationships between the parts and things and solution-sets.

When dealing with large or complex systems (like most software, and software processes) the number of things (scale) and different types of things (diversity) that need to be managed is overwhelming. If we can come up with a modicum of modest, simple rules & principles to govern our design decisions in ways that help us minimize and manage interdependencies, eliminate constraints, and remove waste, then we are on the path to solving the real problem and meeting stakeholder needs in a way that is both simple and sustainable.

I'll close with my collection of favorite quotes on simplicity and simple design from the sources I culled above.

Everything should be made as simple as possible, but not simpler.
-- Albert Einstein
Three Rules of Work: Out of clutter find simplicity; From discord find harmony; In the middle of difficulty lies opportunity.
-- Albert Einstein
For every problem there is a solution which is simple, clean and wrong.
-- Henry Louis Mencken
Think simple as my old master used to say - meaning reduce the whole of its parts into the simplest terms, getting back to first principles.
-- Frank Lloyd Wright
Beauty of style and harmony and grace and good rhythm depend on simplicity.
-- Plato
The ability to simplify means to eliminate the unnecessary so that the necessary may speak.
-- Hans Hofmann
Making the simple complicated is commonplace; making the complicated simple, awesomely simple, that's creativity.
-- Charles Mingus
Everything is both simpler than we can imagine, and more complicated that we can conceive.
-- Goethe
The whole is simpler than the sum of its parts.
-- Willard Gibbs
The pure and simple truth is rarely pure, and never simple.
-- Oscar Wilde
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius--and a lot of courage--to move in the opposite direction.
-- E. F. Schumacker
Besides the noble art of getting things done, there is the noble art of leaving things undone. The wisdom of life consists in the elimination of nonessentials.
-- Lin Yu Tang
Very often, people confuse simple with simplistic. The nuance is lost on most.-- Clement Mok
You can't force simplicity; but you can invite it in by finding as much richness as possible in the few things at hand. Simplicity doesn't mean meagerness but rather a certain kind of richness, the fullness that appears when we stop stuffing the world with things.
-- Thomas Moore
The point of philosophy is to start with something so simple as not to seem worth stating, and to end with something so paradoxical that no one will believe it.
-- Bertrand Russell
The aspects of things that are most important to us are hidden because of their simplicity and familiarity.
-- Ludwig Wittgenstein
Manifest plainness, Embrace simplicity, Reduce selfishness, Have few desires.
-- Lao-Tzu, Tao Te Ching
Simple things should be simple and complex things should be possible.
-- Alan Kay
The key to performance is elegance, not battalions of special cases. The terrible temptation to tweak should be resisted unless the payoff is really noticeable.
-- Jon Bentley and Doug McIlroy
... the purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise.
-- Edsger W. Dijkstra
Simplicity and elegance are unpopular because they require hard work and discipline to achieve and education to be appreciated.
-- Edsger W. Dijkstra
Beauty is more important in computing than anywhere else in technology because software is so complicated. Beauty is the ultimate defense against complexity.
-- David Gelernter
Fools ignore complexity; pragmatists suffer it; experts avoid it; geniuses remove it.
-- Alan Perlis
Technical skill is mastery of complexity, while creativity is mastery of simplicity.
-- E. Christopher Zeeman
Architect: Someone who knows the difference between that which could be done and that which should be done.
-- Larry McVoy
One of the great enemies of design is when systems or objects become more complex than a person - or even a team of people - can keep in their heads. This is why software is generally beneath contempt.
-- Bran Ferren
A complex system that works is invariably found to have evolved from a simple system that worked.
-- John Gall
The most powerful designs are always the result of a continuous process of simplification and refinement.
-- Kevin Mullet
There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult.
-- C.A.R. Hoare
Perfection (in design) is achieved not when there is nothing more to add, but rather when there is nothing more to take away.
-- Antoine de Saint-Exupéry
Simple, clear purpose and principles give rise to complex intelligent behavior. Complex rules and regulations give rise to simple stupid behavior.
-- Dee Hock

Wednesday, May 24, 2006

Six Sigma and Good vs Bad Variation

I briefly touched on Six Sigma (the methdology, not the number/measure) in my previous blog-entry on Cost, Cruft and Constraints, and how Six Sigma methods are about reducing what I called destructive variation:
Six Sigma is about eliminating process variation, but not just any kind of process variation. It's about eliminating "destructive" variation. Destructive variation is value-subtracting variation (rather than value-adding).
Some go too far with Six Sigma and interpret it to mean that ALL process variation is "bad." I don't subscribe to that belief. I think there is intentional variation that adds value, as well as "essential" variation that is either unavoidable, or else emerges naturally (and beneficially) out of the creative & learning processes.

Many have tried for repeatability & reproducibility where it isnt always appropriate. The knowledge creating aspects of software development aren't always appropriate places for procedural repeatability and removing variation. The feedback/validating aspects often are. I think Software CM and testing are appropriate places for this: anything that is appropriate and desirable to automate (like building and testing) would be an appropriate for removing variation and SixSigma techniques.

So just like not all conflict is bad, not all variation is bad! And Six Sigma efforts should (I think) limit their focus to destructive variation for the portions of their processes where it make sense to have both repeatable procedures and reproducible results.

I think I'm actually starting to come up with a combination of Agile, Lean, TOC and Six Sigma that is both cohesive and coherent. I credit David Anderson with starting me down that path. (Look out! CMMI might be next :-)

Tuesday, May 23, 2006

Business Agility Defined

The last few blog entries on agile definitions, and Agile + Lean + TOC have inspired me to proffer up this aliterative definition of Agility in a Business context.

Business Agility is ...
Rapid Response to Change with Optimal Efficiency in Motion, Economy of Effort, Energy in Execution, and Efficacy of Impact!

Is that too verbose? Is it enough to say simply:
Rapid response with optimal efficiency, economy, energy and efficacy!

Note that I dont say anything above about keen sense of timing & awareness to change in one's Environment. Should it? What about Entrusting and Empowering others?

Monday, May 22, 2006

Cost, Cruft and Constraints

My earlier blog-entry on "Feedback, Flow, and Friction" met with mixed reviews.

Many commented that agile development is ultimately about lowering the cost of change. Others noted feedback is important, but unless you respond to it, and take appropriate action, it's not the be-all and end-all it may seem. A few felt the that "friction" wasnt quite close enough to "contraints."

It seems when it comes right down to it, Agile, Lean and TOC are all about trying to eliminate and/or remove the following:
  • Cost-of-change: Agile is about reducing the cost of change by making change easy and catching the need to change much earlier thru continous feedback and close, frequent stakeholder interaction.

  • Cruft: It (cruft) is waste! And Lean is all about eliminating waste in order to maximize flow.

  • Constraints: TOC is all about eliminating constraints, and using the five focusing steps to do it.
While we're at it - Six Sigma is also about eliminating something: variation (but not just any kind of variation). It's about eliminating "destructive" variation. Destructive variation is value-subtracting variation (rather than value-adding).

The phrase "Cost, Cruft and Constraints" doesnt sound as attractive as "Feedback, Flow and Friction." A large part of that may be due to its nonconstructive focus on what to eliminate rather than on what to create.

For each thing I'm allegedly eliminating, I'm gaining something else:
  • Reducing the cost-of-change makes it easier to accommodate change and be adaptive/responsive

  • Eliminating waste helps maximize flow of the production pipeline.

  • Eliminating constraints help maximize throughput

  • Eliminating destructive variation helps maximize quality in terms of correctness, reliability, availability, operability, maintainability, etc.

Monday, May 15, 2006

Pragmatic Multi-Variant Management

I had a rather lengthy post on this subject on the Pragmatic Programming Yahoo group ...

My advice as a CM guy is you do NOT want to use branches or branching to solve this problem. If you have to manage/support multiple "configurations" of functionality for multiple markets/customers, branching is just about the worst way to do it (and this is coming from someone who is an advocate of branching, when done the right way for the right reasons).

The issue is likely to be one of "Binding Time". In your case, you would prefer the binding-time to be either at build-time (such as conditional compilation or linking), or release-engineering time (packaging up the "right" sets of files, including configuration files, for distributing to a customer), install/upgrade-time, or run-time.

One of the prefered ways to do this is with Business-Rules; particularly when it comes to decisions of "variable" policies and/or functionality. With GUI's depending on the kind of variation, you might resort to either conditional compilation or else simply creating separate source-files (instead of branching the same file).

There were some substantial discussions on this topic on CMCrossroads forums that yielded many practical insights and further resources. I recommend them:fantamango77 wrote:
I can say I tried out different strategies in earlier projects already. But not with such a big project. And none of the ways I took made me happy. It always ended up in a kind of hell: Configuration hell, branching hell, inheritance hell.
Yes - and some of those "circles" of h*ll are far worse than others when you look at the overall costs and effort. The bottom-line is that if you have to support multiple "variants" rather than a single evolving "line", you are adding complexity, and there is no way you are going to be able to sweep it under the rug or make it go away.

So it all comes down to which techniques and strategies in which "dimensions" of the project/product will prove most effective at minimizing and managing dependencies, effort and impact by most effectively allowing you to leverage proven principles such as encapsulation, cohesion, modularity, abstraction, etc. in the most efficient ways.

Think about what aspects or dimensions of your project/product are required to be "variable" in order for you to support multiple variants. Do your "variants" need to differ ...
  • in functional/behavioral dimensions
  • along organizational boundaries
  • along multiple platforms/environments
  • along temporal (evolution) dimensions
  • along project dimensions
Figure out which one or two of these are the primary "dimensions" of variability you need to support. Then find the set of mechanisms and techniques that apply to it.

For example, if you need to allow variability primarily along functional and environmental "dimensions", then which of those "dimensions" does version branching operate within? Version branching operates primarily within the space of evolution/time (concurrent, parallel, and distributed development).

So temporally-based techniques are not going to be best suited to handling variation in the behavioral or environmental dimensions, as the isolation/insulation they provide does not most effectively minimize, localize or encapsulate the kinds of dependencies in the non-time-based aspects of the system.

Differences in policy and/or mechanism are typically best handled using a business-rules approach to deliver a single codebase with multiple possible configurations of rules and rule-settings.

Differences in platforms are best handled by well known design and architecture patterns like Wrapper-Facade, and numerous patterns from the Gang-of-Four design patterns book.

Differences in behavior may be best handled by functional/feature selection and deselection "design patterns" like Configurator, to enable or disable features and/or services at post-development binding-times.

Inheritance may be useful in some cases, if the type of configuration needed really does fit a single hierarchical model of increasing specialization. In other cases, an aspect-oriented approach might be better.

Also think about the following in terms of what needs to "vary" and what needs to stay the same:
  • Interface -vs- Implementation -vs- Integration
  • Container -vs- Content -vs- Context
This kind of commonality and variability analysis helps isolate the fundamental dimensions or aspects of variation that need to apply to your project. If something needs to be able to vary while something else doesnt, then "encapsulate the thing that varies" using techniques that separate interface from implementation (or implementation from integration, or etc.) in ways that "keep it [structure] shy, DRY, and tell the other guy."

You might end up using a combination of strategies depending on the different aspects of variation you require and the "dimension" in which each one operates.

Monday, May 08, 2006

Nutshell definitions of Agile development

Over on the Extreme Programming Mailing list, someone asked "Could any one tell me what's exactly Agile Methodology(method) is?", a couple really good responses followed that I rather liked (italics are mine in the excerpts below).

Phlip wrote:
Agile development means using feedback to prevent waste and optimize development.

Software development follows an inner cycle of writing code for new features, and an outer cycle of delivering versions to users.
  • The inner cycle risks waste when we debug too much, or write too many lines. Larger teams also cause waste when one person must wait for another to upgrade their modules.
  • The outer cycle risks waste simply because when customers wait a long time for new features, the odds increase that they will request changes to existing code.
Feedback" means you set up a cycle so your project can tell you about its current status, early and often.
  • The most important feedback for the inner cycle is automated tests. They prevent wasting time debugging, and they help you remove lines of code that are not needed. And they make your code safe for others to change, so they don't need to wait for you.
  • The most important feedback for the outer cycle is frequent releases to end users. If you give them the high value features first, then the odds they will request rework are low. (High value features tend to have obvious specifications.) Then, the odds they will request new features are high, so you repeat. Each new release will reinforce and fine-tune the high value features.
Put together, these processes allow teams to move rapidly to new territory, and to not trip or make mistakes getting there. The dictionary's word for such fleet and sure-footed behavior is "agile".

John Roth wrote:
Agile is a style of project management which lets the project respond quickly to changing requirements. It also usually incorporates frequent releases, or at least the possibility of frequent releases without undue extra project management overhead.

Ease of handling changing requirements naturally leads to leaving the definition of detail to the last responsible moment, rather than having to have all details completely specified up front.

Most named agile methodologies don't specify much outside of project management. Scrum, for example, specifies a lot of project management, a small amount of team practice (put the developers in a room and do daily standups) and gives essentially no guidance about how to actually construct the software.

XP is the only one I know of that specifies all three (project management, team practice and software construction practice) in detail.

C. Keith Ray wrote:
Agile methods react well to changing requirements, permit delivery of working, tested, software at frequent intervals, and generally require less "overhead" than older document-driven formal methods. To enable this reduction of overhead, Agile methods rely on "social" tools and practices (such as shared-workspace, "information radiators", and retrospectives) as well as technical tools and practices like automated builds and automated tests.

Someone referred to James Bach's definition of an agile methodology:
agile methodology: a system of methods designed to minimize the cost of change, especially in a context where important facts emerge late in a project, or where we are obliged to adapt to important uncontrolled factors.

A non-agile methodology, by comparison, is one that seeks to achieve efficiency by anticipating, controlling, or eliminating variables so as to eliminate the need for changes and associated costs of changing.

Steven Gordon wrote:
What makes this question so vexing to so many is that being agile is contextual rather than definitive.

Being lean and principled is not necessarily sufficient to be agile - one must garner feedback from the context (from customers and management as well as ourselves) and adapt appropriately to that feedback to remain agile. Doing the exact same things could be agile in one context and not particularly agile in another.

Tuesday, May 02, 2006

Feedback, Flow and Friction

I think those three words may just possibly distill the essence of Agile, Lean, and Theory of Constraints: Feedback, Flow and Friction!
  • Feedback is, to a large-extent, what Agile is all about. It is about getting continuous feedback quickly and frequently as possible (at all levels of scale) to promote collaboration and synergy and synthesis of the knowledge we gain thru learning and discovery so we can validate it early and often.

  • Flow is what "Lean" is all about. It is about ensuring smooth continuous flow of the value stream, from creation thru delivery, and eliminating redundancy and waste wherever possible.

  • Friction is what "TOC" is all about: identifying and removing the constraints that impose friction on the flow of value and the feedback cycle of discovery and learning.

What do you think? How far off the mark is this? How badly am I oversimplifying?