Segall’s Law says, “A man with one watch knows what time it is; a man with two watches is never quite sure.” While most people intuitively understand this for watches, it’s apparently unfathomable to most devs when it comes to programming. Our code is littered with repetitions of algorithms and data, not only across the company, but also within single applications.
It seems that everyone wants to craft their own watch. We store the same user or system data many different ways with no hope of reconciliation. We copy and paste code all over the place, and then we let it get out of sync. The whole idea of different teams sharing code is ludicrous if we can’t even manage to share code within the same application.
A picture is worth a thousand words
Don’t believe me? Open Windows Explorer and find a directory with a .jpg or .gif file. Open a blank slide in PowerPoint. Copy the .jpg or .gif file and paste it to the slide background. Now paste it to the text area. So far, so good.
Now drag the .jpg or .gif file and drop it in the background. Next drag and drop it in the text area. Whoops! Try this same experiment with formatted text. Notice that you get a smart tag on paste, but no smart tag on drop.
Eric Aside It looks like PowerPoint fixed the image bug in Office 2007, but the problem with formatted text remains.
I’m not trying to single out PowerPoint. Try it with other applications and other data. You’ll notice how data from a paste is treated differently than data from a drop, and it’s not just due to where it’s placed. Each of these scenarios should act the same. The data is identical in all cases. In fact, paste and drop do act the same in Word (nice job).
So why does the same data inserted into a document in roughly the same way produce different results? Well, duh! It’s a different code path. The irony here is that duplicate code paths are often created by copying and pasting the original code itself.
Does anyone really know what time it is?
Having two code paths to do the same work is just like having two watches. Maybe they behave the same, maybe they don’t. Keeping the code paths synchronized with bug fixes and spec changes is a nightmare.
Of course, the solution is to write one routine that does the work and then call that routine from each code path. That’s first-year computer programming fundamentals, and yet we make this freshman mistake over and over again.
But the problem doesn’t begin and end with functions. It extends to data as well. How many bugs have you fixed that were caused by out-of-sync data values? Could these data values have been derived from one value, but were instead kept separately? And don’t even get me started on how often I’m forced to type my e-mail address every day.
Maintaining two watches and keeping them both accurate requires manual synchronization. This is a tedious and error-prone process. It’s much easier to have a single watch. Unfortunately, many of us have a watch, a PC, and a Pocket PC, plus we work with a whole mess of people who have their own timepieces.
Luckily, your PC can synchronize automatically with a network synced to an atomic clock. Then your Pocket PC, your watch, and everyone else’s can be synced to your PC’s time. Automate all that and the problem is solved.
There can be only one
There is a fundamental principle at work here. I call it “sole authority.” Every piece of data should have a sole authority for its value. Every operation should have a sole authority for how it is done. Keeping all your timepieces in sync is possible because there is a sole authority for the current time. Consistent user interface is possible if there is a sole authority for how each operation is completed—for things like painting, data input, and message handling.
Every time you copy and paste code, stop and think, “Am I repeating myself or is this really a different operation? What is the sole authority for how this operation is conducted?” Then act accordingly.
When you are about to create yet another registry entry, stop and think, “Is this really a whole new concept to the user or system, or can I derive this value from another authority?”
If you are asked to create a custom control, think, “Is there an existing authority on how this control should work, and how can I use it?”
For you performance geeks out there, remember that caching a computed result is often slower than recomputing the result, due to faster processing speeds and the gating effect of cache hits.
Everything is connected to everything else
Sole authority becomes much more important in the .NET world. We are hard at work giving our users one authority for their identity, another authority for their calendar, one for their address book, and so on. We are betting that the resulting convenience will be a boon to customers and a boost to our bottom line.
But it only works if we use one method to perform all the associated operations. Doing otherwise not only opens us to bugs and makes our users confused and frustrated, but it also can multiply security holes and increase operational costs.
Eric Aside While the idea of having one authority for identity, calendaring, and so on was good in concept, concerns around trust, privacy, and interoperability caused the notion to fall short in the marketplace.
In software development, too many cooks do spoil the broth. Spoiled broth can give our customers and partners dysentery, not to mention what it does to the cooks. By simply questioning what code or data is the sole authority for every operation or query, we can simplify our code, make it easier to fix and maintain, and give our customers and partners a consistent, pleasant, and intelligent experience.