This principle applies as much to software design, as it does to every other kind of startup, and to keeping a business running, in general.
This post covers the two interwoven phases of software creation:
Everything start from an initial design, of course, but design also occurs in iterations, throughout the development process. So first we’ll look at the initial design, then discuss the implementation methodology, and conclude by returning to some fundamental design principles.
The Design Formula: Usability = Sales
Long term sales depend on providing products and services that people want. To build products that people want, be sure you make them usable. That is the essence of software design.
To do that, you start from the user experience, and design your way deeper down, to the core, until you get to the fundamental library — the modules that will serve as the foundation for everything else.
The Implementation Progression: Start Small, Deliver in Stages
But in addition to design, you also need to develop and deliver. And the best way to do that is to start small and build outward in small stages. That not only keeps the development effort small and manageable (instead of having some huge deliverable due in a couple of years) but, at each stage, you can get additional feedback about usability and how things really need to work.
The other half of the strategy, then, is to build from the core outward, back towards the user.
If you do it right, you choose a function you want the user to be able to perform, and create the core modules you need. Then you create the intermediate modules that build on them, until in the end you have implemented the function the user will access. You’ll start with simple things like “create a file”, and “save a file”. Over time, you’ll add more complex functionality.
The Quality Formula: Unit Testing = Quality
Along the way, of course, you’ll be implementing comprehensive unit tests for each module you create. Those tests accomplish important goals:
- Prevent bugs.
When old modules are used in new ways, the often require small changes. Those changes sometimes cause unexpected consequences in the way the module was originally used. Unit tests identify the problems — immediately, right where the problem is, instead of months later, when some user experiences an unexpected problem.
- Enables agile development.
The process requires that you build outward from a small core, and keep prospective users involved in testing as you go. But, having done an initial design, you can be reasonably certain that each module you develop dovetails nicely with the features you’ll be implementing later. The important point here is that agile development and “waterfall” design can work together. You don’t have to start coding with no design in mind at all — nor should you. But the freedom to change your design is provided by unit testing, as described in point #3.
Unit Testing also Allows for Growth
The third important principle of unit testing is:
3. Permits refactoring.
As explained in How Unit Testing and Refactoring Work Together, unit tests let you rewrite code safely, secure in the knowledge that everything works as it did before. So when that user-feedback precipitates a change to the fundamental design, you can do it without worry about breaking any of the existing functionality.
The Usability Formula: User Feedback = Usable Programs
If you’re using an agile methodology, each deliverable will be handed to the prospective users to play with — which will give you more feedback about how the system needs to operate, to be really usable. (That, after all, is the goal of the system!) That feedback will play out in one of several ways:
- If it requires only a slight modification to existing code, you act on it immediately.
- You tell the user how they’ll able to accomplish their goal in a different (and suitably easy) way, so you’re off the hook.
- You add an additional function to the design list, and begin thinking about the modules needed to implement it.
- If it needs modules you have already built, you may choose to add it immediately.
- If it requires modules that are already in the plan, you add it as a future feature.
- If it requires new modules that need to be designed, you put it on the future-features list, as something to consider.
More About Design
But it all starts with the design, which is predicated on usability. As described in Think from the User In, the important point is start from what the user needs to do, and how they can do it most easily. That’s where your design starts.
It’s a numbers game, too. If a user needs to do one thing 1,000 times a day, and needs to do something else once a month, it’s ok if the action that is rarely performed takes 10 steps. No one minds that. But that thing that is done a 1,000 times a day had better be possible with a single click. That’s important. Do that, and your users will love you.
Developers are Also Users
But it should be noted that developers are also users, when it comes to making use of the modules you build. So in addition to designing for end-users, you need to design for the developer-users who are, in essence, your “early customers”. This is an aspect of usability that is all too often overlooked. The problem is that when you make things harder for developer-users, you impede the pace at which the desires of end-users can be satisfied.
Describe how to drive the car, not how the steering system works. It’s astonishing how many developer-authored whitepapers do the latter. That’s good stuff for the design document, and something that other coders will want to hear. But 95% of the people who are looking at your stuff want to use it.
- Interface Design
Don’t build an interface for your technology, so it can be used. Build an interface that solves user problems. Set up use cases and design an interface that minimizes the number of steps the user has to take in the most frequent use cases, that makes less common cases possible, and that above all makes it easy to remember how to do things. Then use your technology to implement it. And if the APIs get in way, change the APIs!
Design the best APIs you can think of. Do something else for a week. Then write some test applications from memory. When there’s a difference between what you thought the API was as a user and what you thought it should be as the designer, favor the user perspective. Rename the API or refactor to match the way you thought it would work when you were using it. Whenever possible, build your application tests first.
Learn more: Making APIs Usable
Copyright © 2000-2017, TreeLight PenWorks