Once And Only Once Is Not Just For Code

I always understood that everything in code should be done OnceAndOnlyOnce. Even my first BASIC programs did everything OnceAndOnlyOnce. It just seemed like the thing to do. But I've only recently come to understand that this rule should apply to my labor, too. I will work hard to reduce my code, but I haven't been that smart about my labor. Sometimes I'd do a thing dozens of times and only then consider automating it. A lot of the times I'd decide not to spend a day to automate something that only takes me 30 minutes to do manually. Then, months later, I'd notice that I'd done the thing 100 times over the course of the project.

I'm a little slow, so I've had to do that to myself a lot before getting the idea that OnceAndOnlyOnceIsNotJustForCode. For some stories of how I did this to myself on a legacy system written in FORTRAN 77, see LessonsLearnedFromFortran.

Here's a story showing that I can learn, however slowly. One of the members of my organization is caused by management to produce some rather silly reports. To do those reports, they need some statistics gotten from SQL queries against a database. One day they came to me, and I happily did the queries... took all of five minutes. The next day they came to me again, and I happily did them again. The third day, I asked them if this was something they needed every day. The answer was, "yes."

Now that I knew I'd have to do this over and over, it was time to automate it. A half a day later I had an internal web server set up with a cgi script to run a Java program to do the SQL, munch the data, and spit it out in a nice table. The result? I don't have to do the query. Now the person who needs the data does the query. Problem solved.

A week later they need some more statistics added, and the next week still more. Having automated one report, it was easy to add more queries. Now there are half a dozen queries that anyone in the organization can do without bugging me at all. Some produce cooked versions of raw log files, some do database queries. But all of them relieve me of ever having to ever do the task again.

Now, that's what computers are good for!


My first real job was writing test software for a real time OS written (mostly) in ADA that was simulated on a VAX. My work was somewhat brainless translation of a test specification into a test program that exercised the relevant piece of code. The test specs just kept coming... I guess you can see this coming too. Although not how I was expected to do it, I wrote a DCL script that took a cooked version of the test spec and spat out ADA test code.

There is a rider to this. My skills were no longer needed in the company as I had automated myself out of the job. It wasn't that long before I was made redundant.

[As pointed out below, this is not necessarily a bad thing. Some of us even look for opportunities like this, to be able to move on to better things. Smart companies in fact would keep such an employee, knowing that he has a track record of making processes more efficient. This is a means to increased respect and responsibility. And if your employer is silly enough to lay you off--and many are--it's great to be able to go into an interview and brag about such accomplishements. "Through automation, I increased productivity so much, they didn't need me anymore."]

There is a rider to the rider. If I had stayed in that company, I might have been promoted to chief test engineer, and I would still to this day be running and overseeing various unexciting tests. What at the time seemed to be a kick in the teeth was actually responsible for moving me on to a better and more interesting track. So a set back is not always what it seems. This is a lesson I've had twice in a big way so far - I think I've got it now. No really, I don't need it again.

So, how could you automate that lesson?


I get the impression that the XP value you're thinking of is "You aren't gonna need it," and that I violated that by somewhat guessing at future needs. That's a little bit true. What I was thinking of at the time, though, was the XP value of "once and only once," which I think (I'm not an XP expert) trumps YAGNI. I had already done it three times when I decided to automate it.

On the other hand I wasn't doing XP. I'm in a non-XP shop. Although I practice as much XP as I can get away with, the customer does expect me to guess at future needs, both for features and for infrastructure. I think that the customer and I both lose when I do that, but I do the best I can at what I'm asked to do. --

ThreeStrikesAndYouRefactor.


We have a rarely delivered product that (currently) we resurrect, shake the dust off, and plug back in to the rest of our core products. After its delivered, we throw it back on to the back burner. The rationale is that it isn't worth the cost of keeping it maintained on a regular basis. I'm thinking you could make this decision quantitatively. If it costs us X resources (people, schedule, pushing off other tasks) to make it maintainable upfront, Y resources every year to maintain it, but doing the reactive fix it up every delivery costs Z resources, then if

future_value(X) + Y*years > Z * deliveries per year

its not worth changing our policy.

This could move to a page called MaintainOrRebuildEachTime?. The discussion applies to decision on when to refactor.


I think OnceAndOnlyOnce is also the main principle of OpenSource. Why should we do some work which already someone else did. OpenSource is already ExtremeProgramming. I disagree. (Could you be more specific as to what you disagree with ?)

BUT OpenSource isn't really yet OnceAndOnlyOnce. How many pieces of open source code are there out there that deal with reg expressions? It's actually a huge hole in OpenSource. There is no real method for refactoring OpenSource and distilling the code down to fewer more powerful modules.

There's some techniques that are helpful in OpenSource. Rather than bundling all the little pieces (regular expression parser, etc.) that your program needs into one huge block, you can merely list all the pieces your program needs ("dependencies") in your package, then apt-get ( http://www.debian.org/doc/manuals/apt-howto/ch1.en.html ) will automatically fetch all the required pieces when you install it. (And if some other program depends on some of the same stuff, apt-get is smart enough to fetch it OnceAndOnlyOnce).

I agree that better tools to make refactoring OpenSource easier would be very, very nice.

[OnceAndOnlyOnce is no more common in OpenSource than within any large company. "YouKnowYoureInaBigCompanyWhen... you find out that another group is working to create a product just like the one you are creating... even using the same specs!" However, there are more opportunities for reuse in OpenSource than in ClosedSource. Since you get the source code, you can make better use of what reusable components there are. Since you get to contribute to the source code, you have an opportunity to make reusable what parts can be made reusable.]


OnceAndOnlyOnceOnWiki

http://wikinodes.wiki.taoriver.net/moin.cgi/OnePlaceForEveryIdea


IncludedReplyDestination claims that CORBA fails to work through some firewalls because data is duplicated in the packet, then allowed to get out of sync -- violating OnceAndOnlyOnce.


Would it make sense to move most of the current content of OnceAndOnlyOnce to something like OnceAndOnlyOnceForCode?, then leave OnceAndOnlyOnce as an index ? The index would briefly talk the general OAOO principle and then have a list of links to pages of specific examples: code, requirements, documentation, manual tasks that could be automated, sharing code between multiple programs (especially open-source), etc.

Or should we just have CategoryOnceAndOnlyOnce? ?


See also: OnceAndOnlyOnceForRequirementsDocuments, SeeOneDoOneTeachOne, AutomationIsOurFriend, ThreeStrikes

Contrast: LotsOfCopiesKeepStuffSafeTm


EditText of this page (last edited August 16, 2005) or FindPage with title or text search