The Art of Complexity
Harnessing the tension between simplicity and complexity
The Art of Complexity
Harnessing the tension between simplicity and complexity
- 5 minute read
There is an inherent complexity in all systems. By their nature systems are comprised of multiple component parts interacting with each other to solve a particular need. Like all good things, complexity is about balance, too little and your solution may not deliver, too much and you're in danger of giving people sleepless nights. Layering up on ever more complexity doesn't necessarily result in more optimal solutions, sometimes better outcomes can be achieved with significantly less complexity. So how should complexity be approached and why do we care so much about it?
As designers we naturally lean towards simplicity. The design process leads us to question each decision as we design, each stroke of the stylus, each element being added or modified is for a purpose. Is this UI going to engage and hold a users attention? Are we driving towards the desired outcome? Does the response pathway minimise points of friction? As developers our job is to realise a design, to bring it to life, to make it work on a variety of different devices. There is an almost infinite number of ways we can achieve this, which in turn leaves the door open to a huge number of decisions that will need to be made along the way.
There is a tendency as developers to view complexity through something of a lens when compared to the view of a designer. These differences in approach highlight the natural divergence in the way creatives and developers think. We lean into these differences as it continues to be one of the most compelling reasons we have for encouraging our designers and developers to collaborate as extensively as possible. Often the two disciplines, design and development, are viewed and approached as polar opposites, in no small part due to creative brain vs developer brain, but in our experience in they are far from mutually exclusive. Good design stems from not only understanding the need, but having a firm grasp of the technical, be that material science and processes in real world manufacturing, or in the ever evolving digital space. It’s just as important for developers to step back as it is for designers, take a deep breath and ask the right questions.
Let's take an example from a project timeline, one that will regularly present itself as the project moves into the development phase. There is in modern development a tendency to utilise what we call the lego brick approach, which is to say start with a base then continually add bricks to meet the need. Most of the bricks are developed (and hopefully maintained), by third parties. Choosing a base is the first challenge, it should be right for the project, which in itself is a major decision. Often developers will lean towards a preference when perhaps the project doesn’t necessarily require or support it. The second part, the addition of bricks, is where complexity can very quickly ramp up and have unintended consequences, including negatively impacting development scope.
These bricks, or packages as we call them, are reached for to add functionality or features. The use of packages offers advantages, including rapid development, but more often than not however they are feature rich, meaning they have many more features than is required for the project. But to solve the problem at hand the package as a whole is accepted into the codebase. What is now apparent is that a significant portion of the package code is redundant, and with each new package comes additional redundant code. All of which is continuing to stack up, just like those lego bricks. We're not suggesting this whole approach is inherently bad, what we are saying is that each and every package needs to be carefully considered, alongside whether it’s introducing a level of complexity that is acceptable because it’s solving a problem, if it’s potentially creating new issues, or if its extending the required work effort through too much complexity. To put it another way, it’s about choosing the correct lego brick for the job, not just because it snaps into place. In this part of the project timeline, finding the balance is considering if spending a little time developing some of our own code at the point of reaching for another package would be more beneficial, as we know it will quickly repay itself as we move down the line. Adding complexity in code leads on to added complexity down the line, from increased building and testing timelines, to additional infrastructure requirements to hosting costs or cloud services fees.
But that is not the final word, because equally important when considering complexity is the ability to maintain a project. For every additional layer of complexity, the maintenance requirement increases. Creating maintainable products is vital because the end of a project is never launch day. Adding new features, or extending existing features, on a project that has poor maintainability is both more time consuming and more expensive.
Thinking of complexity as a flexible, fluid concept does not always come naturally. In well designed solutions complexity plays a vital role and something that we encourage our team to consider throughout the product lifecycle.
Harnessing the natural tension between simplicity and complexity to create solutions with necessary, well considered complexity is what we do best. We have a lot of experience across a large number of diverse projects, and we’re always thinking about how we can better leverage complexity across our deliverable disciplines. We’ve forged many long term client relationships, and it’s this kind of full end-to-end solution thinking which helps us keep our relationships strong.