OK so now we’ve got two important things that we know. First is the importance of good requirements gathering, second is the importance of deploying early and often to end users.
The next part of the puzzle is the actual design. How are we going to solve the problem? When I’m talking about design rules here I mean both UI design and internal code structure.
- A simple design is best.
- A focused design is best.
- Don’t try to solve everything up front, let the design flow and evolve as you work with the problem. Start small and simple and build out.
Another thing is that the software must be easy to use.
- Putting in the effort to make software easy to use means that effort is put in once, by you, the developer. Hard to use software will torture your users and place demands on them every day.
- Easy to use does not mean that it should be so infantile that it actually doesn’t solve the problem or makes it more onerous to solve than it needs to be just in the name of avoiding putting any cognitive strain on the user whatsoever. Depending on your users you can expect them to do some work and learn some concepts to use your software.
Unfortunately you don’t know what “easy to use” is, and neither do any of upper management, analysts and whoever else. The only people who know what “easy to use, but still powerful enough to get the job done” is, are end users. You can have some ideas, but they’re just ideas until they’re tested by putting them in front of end users. Even before MVP you can bash some end users over the head and drag them back to your cave and force them to try out your software. This is called Hallway Testing and it is super important and no one does it, and then people write long articles about why there’s so much bad software in the world.
Make a prototype
A basic implementation of your design must be available quickly.
- Make a prototype and iterate.
- A prototype should be ready in the first few weeks of the project.
As soon as the prototype is good enough (good enough means embarrassingly bad, but solves a problem or is useful to someone), then it is an MVP and must go to end users.
- Take into account fundamental requirements when designing. So for example security, which devices the program will run on, whether or not multi-threading is needed, business rules, that kind of thing… initially the prototype doesn’t have to implement solutions that match these requirements fully, but if they’re truly requirements that will be part of a solution eventually then the prototype must be designed with them in mind. For example if you leave out security but intend to add it later, your design must reflect that and make it so that when you do add it in, it is as easy as possible.
One thing to be vigilant against is feature creep. Feature creep is when you have something that does X and someone says “But if you just did Y and Z then it could do A, B and C”. ivermectin for diabetic patients Remember, keep your solutions tightly focused. Software should not be like Julius Caesar (every man’s woman and every woman’s man). It needs to solve a problem. Extending it to solve every problem under the sun will make it unfocused and complex, and that is death to any program.
Things that make a design succeed
- Software that is easy to use. That means it must follow UI conventions (little X in top right corner to close, Ctrl-C to Copy, Menu bar at top of screen, that kind of thing) and it must fit with their mental model of the problem. E.g. if you’re writing banking software the user must “Perform transaction” not “Create new TransactionModel” – terminology used in the program must fit with the problem domain, and this extends to the internals of the program too (Domain Driven Design).
- Software that solves a problem that people actually have (as opposed to one that the software designer thinks they have).
- Developers who are responsive to user feedback.
- Fixes that flow back to users quickly.
Things that kill your program
- Inflexible design that is hard to change. Usually arises, ironically, either as a result of a massive design effort up front to design the Holy Sword of Justice or at the opposite extreme, as an undesigned ad-hoc amalgamation of features resulting in the Pit of Despair. Or for fun and profit you can implement the design of the Holy Sword with an ad-hoc mess of code and create the Unholy Bowl of Spaghetti.
- A slow release cycle and a slow feedback loop from end users to developers and back. In this context slow means that you can’t release without a week notice. Ideally you should be able to code a fix and push out a release to production within hours or at least the same day routinely. I think that a lot of enterprise software suffers from this. Enterprise software tends to require sign off from a thousand managers before the poor dev who fixed the bug (and was roundly criticized for creating it in the first place, and ordered to write more unit tests) is generously allowed to stay up until 2 am on a Friday night deploying. When the loop is slow, the design can go astray much further before being pulled back on track by user feedback. This is more expensive and difficult, and results in much more wasted effort. Also users will go elsewhere if they have the option and their concerns are not addressed in a reasonable time frame.
- Bad error reporting. When things go wrong your program must holler loudly. It mustn’t pretend like nothing happened.
- Weird licensing. Users have limited scope and patience for understanding complex legal stuff or jumping through a million hoops to prove that they didn’t pirate your software. If you make it onerous they’ll just not use your software.
- Poor customer support. Customers don’t have to use your code – they’ll find another way if they’re not looked after.
Things that surprisingly do not kill
- Terrible bugs. (I’m looking at you, Microsoft Windows). Just make sure that when they’re reported they’re prioritized and the fixes are available in a reasonable time.
- Terrible looking UI.
- Running slow, locking up, freezing and crashing. As long as it solves a problem, it will be tolerated. Also as long as it doesn’t run like 20 minutes to do anything slow and doesn’t corrupt the file containing a user’s entire week of work.
- Competitor software. There are always trade-offs and it’s very rare that two pieces of software are directly comparable anyway. Unless you price it at 5 ounces of gold per licence you should get at least some market traction.
Things that users hate but will put up with
- Tediousness. Forcing your user to do the same thing time after time is a design smell. Try to find a way to make it possible to do bulk operations.
- Complexity, if the need is great enough and there’s no alternative. But try to make sure there really is no way to simplify your interface, because making your users hate your software is not generally regarded as best practice. ivermectin subcutaneous vs oral in dogs However, in the search for simplicity, do remember that clean UI which babies the user so much that they can’t solve their problem or makes the problem tedious to solve is completely pointless and will irritate them just as much as unnecessarily complex UI.
If your program is terrible enough but still does something essential, some users will develop Stockholm syndrome and fall in love with it, but it’s not a great look. As long as you continuously check your design against user feedback you are pretty much guaranteed to come up with something good, it’s when the loop is broken or slow that things get dicey. ivermectin pour on cattle for goats Unfortunately it’s kind of natural to want to keep your software hidden until it’s “ready” – management also like to present their clients with polished products. So the mindset of sending it to end users in an embarrassingly bad state is very unnatural and you have to fight even your own brain in order to implement it. Most “agile” development that I’ve encountered does almost everything right except for pushing unfinished stuff out the door, and if you’re not willing to do that, it kind of stuffs up everything.