Design as Code

Bernie Durfee
The Startup
Published in
5 min readJun 25, 2019

Software Engineering has come a long way. From the primordial days of “hacking it until it works”, through the dark ages of project manager driven waterfalls, to the gilded renaissance of Scrum; the processes around developing software have been refined and redefined many times over.

It has been encouraging to witness the attention to robust process expand beyond the development of core application logic to infrastructure with the advent of Infrastructure as Code. After all, infrastructure is a direct extension of your code in that your code calls lower level libraries, those libraries call drivers, those drivers talk to the OS, which in turn talks to hardware, which does the stuff you asked your code to do in the first place.

Software really is just software all the way down.

Which is why there is now an abundance of tools and frameworks available for managing and configuring operating systems, databases, networking components and other infrastructure. You can now carefully control almost every instruction that’s executed from the high level language you use daily all the way down to the CPU. Treating infrastructure as code makes your application behave more consistently, which makes it more easily testable, which makes it more robust (assuming you test it), which makes it better than it would have been if you had simply thrown your code over to an operations team to run on any old OS on a random server they happen to have racked up at the moment.

Looking downward through our software and paying close attention to all of the underlying components that make it run has allowed us to create more stable and scalable software. Yet, if we look upward, at the requirements, user stories and design artifacts upon which our software is based, we still very often see gaps in the rigor around how those artifacts are managed.

In particular, I’ve noticed that mockups, which are critical to providing a satisfying user experience, are not nearly as rigorously controlled as the code that makes those mockups come to life.

It’s common, in my experience, to see mockups emailed around, posted in chats, dropped into shared folders or otherwise strewn about with little regard for organization. It certainly wouldn’t pass muster with many organizations to treat source code this way. Yet mockups, that themselves drive the creation of many thousands of lines of code, are often left out of the same revisioning process that controls that very code.

Developers depend on mockups to guide their development. Lack of rigor and control of those mockups will have negative impacts on the quality of the overall project.

Some examples of specific issues caused by poor control of design artifacts:

If a developer doesn’t know where to find the latest version of a mockup, they will often waste time implementing components or behaviors that may have already changed.

Without a methodology for revisioning mockups, it’s often difficult or impossible to review exactly what has changed as mockups evolve over time.

Mockups without annotations or narratives are like complex source code without comments. Code and designs define state and behavior; comments, annotations and narratives define intent. Trying to implement a design with no notion of intent is guaranteed to lead to assumptions; assumptions are often wrong.

The current state of process rigor in the design space is generally lacking. In my experience most teams haven’t yet developed or adopted a strong set of controls to ensure clean delivery of design artifacts to development teams. Though, I am confident that, as with other aspects of software engineering, the tooling and processes around user interface design will find a sweet spot between the chaos of no control and the creativity stifling burden of excessive governance. Something agile, but not fully Agile.

In the meantime, if you are still on the chaotic side of the control spectrum, here are some basic strategies that can be implemented to help ease the transition from design to implementation. I’ve seen these strategies put into action using a variety of tools and they do help. I hope they can help you.

Establish a clean, well organized design artifact repository

At a minimum, the repository should represent the latest version of the mockups that are to be used for implementation. Though, ideally, the artifacts should all be versioned so that it becomes clear what aspects of the design has changed over time.

Establish a formal mechanism for reviewing changes

Mockups are in fact code written (drawn and annotated really) in a visual and textual language by designers. As with code, mockups can also have defects: typos, mistakes, inefficiencies, confusing stuff, etc. As such, design defects ought to be captured the same way that code defects are captured, as issues in an issue management tool and not in email, chat or sticky notes.

Design issues should be assigned to the design team, who can then resolve the issue through a fix or close the issue with some rationale to describe why the design choice is not, in fact, an issue. Using a proper tool to capture design issues and their resolution enables better communication and creates a knowledge base for future reference.

Establish a routine for walkthroughs

Developers ‘consume’ mockups in the same way developers ‘consume’ an API. A design mockup is simply a way for a designer to describe to a developer, using shapes and text, what a user should see and how interactions work.

When an API changes, developers appreciate having release notes that explain what and why the changes to the API were made. Even better, to have the API developer meet and explain the changes and answer questions in person. This same process should be adhered to when the design changes. Developers need to understand those changes immediately. Developers also need to understand something about the intent of those changes, so that they can provide feedback and have a better feel for how to implement the new design.

The practice of carefully controlling source code is a critical aspect of producing high quality software. That control should extend through the software you write and down through as many of the underlying layers of other software that you depend on. That control should also extend up through the layers of requirements, documentation and other artifacts that define the look, feel and behavior of your software. After all, it’s just code all the way down and up, no?

Because this post is about details…

--

--

Bernie Durfee
The Startup

IT Professional; Software Developer; Software Architect; Habitual Musician