Monday, October 25, 2010

Everything Is Interface

There’s a myth that programmers are divided into flighty, sensitive types who can create beautiful user interface but can’t do any heavy lifting, and code jocks who can write multithreaded servers but don’t understand usability.  In truth, everything is user interface.  For your program to do anything, it must interface with something else, be it the operating system, a server, another program, or a human being.  And someone is going to have to learn that interface to use your program.  Source code itself is an interface between the programmer who writes it and the poor slob who has to maintain it.  Computer languages are interfaces between what you can understand and what a computer can do.  If your style of user interface is illogical and inefficient, then your coding style is probably the same.  As a programmer, you should strive to write code that is as slick and easy to use as a good user interface. 

Since all code is user interface, anything forbidden to user interface is forbidden to code and vice versa.  If you wouldn’t cover a screen with dozens of buttons, you shouldn’t write a class with dozens of public methods.  If you don’t use goto because it makes your code confusing and buggy, you shouldn’t force your users to visit screens at random to get their work done.  If you don’t want your users entering their data in a huge free-form field, then you shouldn’t store data in some giant string that needs to be parsed.  If you wouldn’t make your function’s actions depend on a mysterious global variable that’s squirreled away in some header file, you shouldn’t make your program’s behavior depend on a global setting that’s hidden in some inaccessible menu. 

This idea of code as interface goes deeper than just the surfaces I’ve been talking about so far.  When you write a method, the method signature is an interface between the code in that method and everything that calls it.  The public methods of a class are an interface between that class and the rest of your program.  Your logging statements are an interface between the program and whoever has to debug it.  What structure you choose to store data in is an interface between the values stored and the code which uses those values.  Everything is interface, and you must always keep that in mind as you code. 

Code itself is an interface because code is written to be read.  You will read your code months after you wrote it, maintenance programmers will read your code to fix all the bugs in it, and if you do things right, your testers and doc writers will know how to read code and be doing that to do their jobs.  Code doesn’t exist just to perform some action, code exists to communicate what the action is and why we’re doing it.  If code wasn’t meant to be read we’d use _1 and aBc as variable names.  Code is meant to be read so must be readable. 

Programmers have trouble coding these interfaces because they believe they’re interfacing with a computer.  But interfaces almost always boil down to an interface between people.  You may never meet this other person, they could be a language designer or a maintenance programmer; they could be using your server as a backend for their own web site or installing your software on their desktop.  Whoever they are, the decisions you make need to keep them in mind.  Programs are limited not by the computers that run them, but by the humans that use them. 

How many projects fail because these human factors are never considered?  Cool ideas get run into the ground all the time because nobody can understand the implementation.  Projects get patched to death by maintenance programmers who can’t understand them because the original developer is too busy or unavailable to explain it.  Programmers forget why they made some decision in the code and so revisit the same questions again and again and again with management.  Clumsy interfaces generate excessive calls to support, preventing a project from scaling beyond a handful of customers.  The success or failure of any project depends on whether any attention is given to the human beings involved. 

This is why I’ve called my blog Hacking the Ultimate Machine.  The human brain is the ultimate machine and understanding what it can and can’t do is central to being a good programmer.  Ignoring human capabilities and limits means ignoring the capabilities and limits of your own work.  And that means putting out software that is no better than the average half-baked junk.  Paying attention to the human interfaces that make up your code is necessary to achieve anything worthwhile in programming.