The Bizarro World of the Developer
As developers, we work with clients from a number of different business types and industries. Over time I’ve noticed that each of them seems to live in their own world. The loan officer I work with for a bank talks about the “banking world”. The owner of a steel distribution company talks about how things are in the “steel world”. A restaurant owner refers to the “food service world”. It’s enough to give credence to the many-worlds interpretation of quantum mechanics.
In one sense, this is kind of funny. I often want to remind these clients that they live in the same world as the rest of us, and while there are specific things they do differently, the same general business needs and rules apply in their “world” as in everyone else’s. In fact, we bring a lot of best practices and good ideas from other worlds to theirs.
On the other hand, I’ve come to appreciate what they mean as I consider the “developer world.” Some things that we take for granted in the “real world” are different from, or even seemingly opposite to, how they are in the “real world”. Some of these differences are so stark that older readers may start thinking of the Bizarro World of the Superman comics they read as a kid. Younger readers, or those stuck watching cartoons with their kids, may think of SpongeBob’s Opposite Day.
In one sense, these differences are kind of funny, or perhaps ironic. (I say “perhaps” since I don’t want Alanis Morissette’s hate mail.) In all cases, though, I find these differences thought-provoking. Maybe by sharing the strange rules of the “developer world” with clients and with other developers, we can improve communication between the denizens of the developer world and those who dwell on other planets… or maybe even those in the real world. Below are just a few examples.
Simple versus Complex
It seems as though nearly every potential client wants us to create a “simple” solution. Of course, we strive to always make solutions that are simple to use, but clients often think that means the solution will be easy to build.
The odd fact is that a solution that is easy to use is almost always complex to build. Most often, what makes a solution easy to use is that the solution is “smart”. It “knows” what you mean from as little input as possible. On the other hand, the simple approach to building a solution creates an interface that’s complex for the user; the user needs to tell the solution every last detail.
Consider putting a customer name on an invoice. The simple way to build this is with a drop-down list, or even just free text. We can build this in a matter of minutes, or even seconds. The user may even find this simple. So why make things more complex? Well, there are a number of other things going on here. If you enter a customer name and there’s no matching customer in the system, you’d expect that customer to be added, so you could use them again on future invoices. If there’s more than one customer with that name, you’d expect the system to help you pick the one you mean. If there’s only one customer with that name, you also want to be sure that if the customer’s name changes later (“Chris” becomes “Christopher”) you can still tell that this invoice goes with that customer, even though the name doesn’t match anymore. If you run a report of invoices, you want the “Chris” and “Christopher” invoices to go together, even though the name was different.
Building all these “smarts” into the solution, even just for this one customer field, can be somewhat complex. By using complex methods, though, we can make the user experience much simpler.
The upshot of this is that when a potential client tells me, “I want a simple solution”, what I hear is, “I want a simple interface and I expect you to be able to do it quickly”. What I’m thinking is, “If this solution is going to be simple, it’s going to be complex to build.”
More complexity during development, where we think through a complex set of possibilities and create complex functions and rules to accommodate them, means a simpler solution for the user to use.
“Most of the Time…”
Another one I often hear is “Most of the time…”, as in “Most of the time the customer’s already in the system” or “Most of the time we don’t charge for shipping.” I understand that when I hear this, the customer is trying to make things easier on us. He or she believes that if something happens ninety-nine times out of a hundred, then that one exception is somehow easier to accommodate.
My response to this is often, “Do you want the system to work ‘most of the time’?” I’m not (entirely) being snide here. Sometimes the exception really is so rare that it makes sense to work around the system with some offline solution on the rare occasions when the exception occurs. Almost always, though, the client wants the system to work all of the time, not just most of the time.
In the “real world”, frequency correlates to difficulty. In the real world we can use a rule of thumb to get the right answer or do the right thing most of the time. Not so much in the developer world. Programming something that will happen once a year isn’t any easier than programming something that will happen a hundred times a day.
“Most of the time” is actually just one example. See also “rarely”, “sometimes”, “a few”, “usually” and “almost always”. It’s worth considering that in Aristotelian logic, all of these become “some”. From a logical standpoint, all of these phrases describe “some” cases, whether they occur “almost always” or “almost never”.
Bugs happen. I’d love to say that none of our solutions ever have bugs, but that’s the equivalent of saying that I’ll never make another mistake. No matter how much we test, there’s no substitute for the end user kicking the tires and using the solution the way they are going to use it. At some point, our own testing even becomes counter-productive, because we’re eating up hours, and therefore money, doing testing, but we’re not the best people to test for certain types of errors.
When bugs happen, there’s a strange misconception that often takes place. The client thinks that the magnitude of the problem is equal to the magnitude of the effort to fix it.
Consider all the customer names “disappearing” from all the invoices. Something like that is almost guaranteed to garner an urgent email with “HUGE PROBLEM” in the subject line, and the client wanting to set up an urgent meeting to discuss how to fix it. Truth is, a problem like that might be as simple as moving a semi-colon in a calculation, and poof! Problem solved. Panic subsides.
The flip-side of this is much less satisfying. During a meeting, the client says, “Oh, by the way, we have a small problem with the cost on a few of our widgets. I’ll shoot you an example. No big deal, though, right?” Thing is, that could just as well involve a complete rewrite of the underlying tables, relationships and calculations that get us an accurate cost. It may look like a tiny problem to the client, because it affects only a few items, but it could take a hundred times longer to fix than the “HUGE PROBLEM” above.
It’s almost comical how often the client perception of the “size” of a change or fix is exactly opposite the magnitude of the actual work. I can’t tell you how many times a conversation starts with the client saying, “I’m not sure if this is even possible, but…” and ends with me making the change before they’re done talking. Likewise, conversations that start with “Hey, I need a quick change …” often end up being the beginning of a series of long meetings, lengthy discussions and hours-long development sessions. It’s actually gotten to where I get a little nervous when a client says “quick change”, but I hardly flinch when a client contacts me about a “huge problem”.
One more: Those of us in the “developer world” have a different concept of the impact of volume, specifically as regards number of records.
Sometimes this comes up when a client wants a change to a large number of records. They think, naturally, that the change will be more difficult because it affects 100,000 customer records, or 500,000 activities. Truth is, the change we’ll make is to a single calculation that affects all records. At worst, we might have to wait for a progress bar as we update all the records. Aside from that, though, the actual change we’re making (the script or calculation we have to write) doesn’t take any longer for 500,000 records than it would have for 100.
This especially comes up when we’re migrating data from an old solution. Clients are always trying to come up with ways to limit the number of records we have to migrate. “What if we create an archive file?” “What if we leave off everything more than a year old?” I appreciate the desire to help. I really do. However, unless you have so few records that we can manually just type them in, writing a migration routine for a million records doesn’t take any longer than one for a thousand records. The progress bar is just longer, in which case I can turn off the meter and go get lunch until it’s done.
It’s a funny little place, our “developer world.” Hard is easy, complex is simple, big is small, and rare events loom as large as frequent ones. Most times, the difference makes us look like magicians. The thing the client thought was going to be difficult or even impossible turns out to be a piece of cake. The flip-side takes a bit more explanation; the thing that the client thought was a piece of cake takes (and deserves) lots of thought and attention.
As a developer, it’s sometimes difficult to interpret from English to Developerese and back. It’s important for us to keep these differences in mind when we’re talking to clients, so there’s no misunderstanding.
Hopefully, this review of a few of the differences will be thought-provoking and informative for developers and clients alike, though, so that we can improve our communications. Who knows, maybe it’ll even lead to a United Federation of Planets!