"Kanban is the science of not trying to do too much at once"
Stephen Palmer, 2012

"What we don't like is needless complexity."
Richardson, Ruby, RESTful Web Services, 2000

"... the most significant complexity of many applications is not technical. It is in the domain itself, the activity or business of the user. When this domain is not handled in the design, it won't matter that the infrastructural technology is well conceived. A successful design must systematically deal with this central aspect of the software."
Eric Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software, 2003

"Our primary tool for design is abstraction. It allows us to effectively use encapsulation, inheritance, collaboration, and other object-oriented techniques."
Rebecca Wirfs-Brock, Alan McKean, Object Design: Roles, Responsibilities, and Collaborations, 2002

"When people are factored in, nothing is simple. The complexity of individuals and individuals working in teams raises the noise level for all projects."
Ken Schwaber, Mike Beedle, Agile Software Development with Scrum, 2002

"We break a problem down into smaller and smaller problems until we have reduced the size of the problems to something we can manage,"
Stephen R. Palmer, John M. Felsing, A Practical Guide to Feature-Driven Development , 2002

"Human brain capacity is more or less fixed, but software complexity grows at least as fast as the square of the size of the program."
Gerald M. Weinberg, Quality Software Management: Volume 1 Systems Thinking, 1992

"The complexity of software is an essential property, not an accidental one. ... Many of the classical problems of developing software products derive from this essential complexity and its nonlinear increases with size."
Frederick P. Brooks, The Mythical Man-Month, 1995

"As the number of people increases, the ways they can interact tend to multiply faster than you can control them."
Gerald M. Weinberg, Quality Software Management: Volume 1 Systems Thinking, 1992

"Our failure to master the complexity of software results in projets that are late, over budget, and deficient in their stated requirements."
Grady Booch, Object-Oriented Analysis and Design, 2007

"The fundamental task of the software development team is to engineer the illusion of simplicity"
Grady Booch, Object-Oriented Analysis and Design, 2007

"Abstraction can reduce complexity by spreading details across a network of components"
Steve McConnell, Code Complete: A Practical Handbook of Software Construction, 2007

"Information Technology is 80% psychology and 20% technology "
Jeff De Luca, www.nebulon.com

The best software designs are ingeniously simple. They are elegant. Great software designers strip away all unnecessary complexity, hiding unavoidable complexity behind well-chosen abstractions.

Elegance is a word that traditionally conjures up images of tasteful opulence, refinement, and grace; of swans appearing to glide effortlessly across the surface of a lake or gentle, meandering river. Elegance is epitomised by a lack of clutter, fuss, and complication. Of course, behind the appearance of effortless elegance may lie considerable hard work. The swans may be paddling frantically under the surface of the water to counter a strong current, and a suite of elegant rooms may have taken hours of painstaking cleaning, arranging and rearranging.

In software development, as in mathematics and engineering, an elegant solution achieves the maximum desirable effect with the smallest or simplest effort. Many mathematicians, engineers, and computer scientists derive great satisfaction from discovering a simpler, less wasteful solution to a problem.

In software development, inexperienced developers are often tempted to include complicated, clever ticks or obscure programming language features in their work. Designers are often tempted to over-engineer by adding multiple levels of flexibility or a myriad of configuration options. In both cases, the price paid is unnecessary complexity, fuss, and clutter, adding significant time and effort to testing, reviewing, and documenting the designs and code. In addition, the software is likely to be harder to maintain and extend, and frequently harder for the users of the software to learn and use correctly.

Unavoidable complexity in software comes from a number of sources including:

  • complexity in the problem domain (real world)
  • the need for increased speed and efficiency (optimisation)
  • the technical nature of the software (e.g. thin client, service-oriented, real-time, high-performance, etc)

Dealing with this inherent complexity is the job of abstraction and encapsulation, hiding the complex details of the specifics behind simpler interfaces, usually object-oriented or service-oriented. Picking better abstractions, better service, better classes requires ability, experience and insight. The most elegant, simplest design that does the job is rarely obvious at the start of a software development effort. It can take considerable, collaborative and iterative effort to arrive at what then seems obvious in hindsight. Software design is a process of ongoing discovery and refinement.

Fortunately, software development teams do not need to start the discovery process from scratch. Strategies, patterns and techniques like 'Modeling in color', 'Streamlined Object Modeling', and 'Domain-Driven Design' can significantly help pare down complexity in the problem domain. To optimise performance, proven, published algorithms, and data-structures can replace simpler, less-efficient implementations leaving interfaces unchanged. Finally, good design patterns, proven coding idioms, and effective libraries and frameworks (open-source or commercial) can help address the complexity inherent in type of software being constructed.

In recent years, Apple have come to be synonymous with elegance in the design of computer hardware including everything from desktops, laptops, and tablets to smart phones, music players, and related accessories. The harder challenge for Apple is to maintain, create and integrate the same level of elegant design throughout the software that runs on theses devices and behind them in 'the cloud'; something they have usually done very well when compared to their competition but far from perfectly when compared to the design levels of their own hardware.

In addition, I do not believe it is possible to analyze the functional requirements of a desired software system without making assumptions about the structural parts and components of that system. In making those assumptions we are synthesizing a solution, we are designing. You cannot ever fully separate requirements analysis from design, and analysis and design are an inherently iterative process. Nevertheless, iterative analysis and design does not mandate that it must always be done through the medium of source code.

Follow me on Twitter...