Abstract With Once And Only Once

From AbstractWithGoalInMind: "Abstract" means, "to ignore irrelevant detail." So there must always be a goal, a test of relevance.

Compare OnceAndOnlyOnce. You implement a concrete class pragmatically. You implement another ditto. You notice that the classes have a lot in common. You refactor to make one a subclass of another. You notice that the top one has just a few methods overridden in the bottom. You decide the system would look better if there were a class at the top with no concrete implementation of those methods, and two parallel subclasses with those methods. You do it.

The result is that you have an abstract class with two concrete subclasses. You have done it with no goal in mind other than to reduce redundancy in a particular way.

I've done this exercise and wound up with a very nice implementation of the classes in question and never had a goal in mind of the kind of abstraction I was doing. It's almost mechanical. Very interesting.


And each step of the way you had a working implementation with no stubs yet to be implemented, no worry about whether you were going to be able to implement (and like) a pre-conceived design. By building the classes one step at a time, you arrived at a better end-point than you could have pre-conceived. But it did take the willingness to incrementally modify existing design and implementation. Which is in accord with the philosophy of ChristopherAlexander. --ScottJohnston


I am currently teaching programmers that there are only two criteria a program must meet to be a well-built program:

Almost everyone grants the first criterion without demurrer, but controversy is usually stirred by the second. My rationale for making the bold statement is straightforward: all the other definitions of well-built software that I've used spawn more (and harder) questions than they answer. OAOO as an abstraction goal is no magic coin: there are still lots of judgement calls to be made. But the close calls seem fewer, easier to make, more open to reversal, and more coherently argued over. -- MichaelHill


"No goal in mind other than to reduce redundancy"

This isn't a surprising result. By the time you have the two classes, you already have your relevancy criteria; they are implicit in the class interfaces.

Abstraction is tied to polymorphism, which is about treating objects which are different at one level of abstraction as if they were the same at another level of abstraction. When you notice the classes "have a lot in common", you're identifying a level of abstraction at which they can be treated the same.

I don't see any conflict between the two approaches. Reducing redundancy is a suitable goal for abstraction. -- DaveHarris


(Some discussion originally on OnceAndOnlyOnce:)

Although OnceAndOnlyOnce is a good maxim, it doesn't address the situation where two notationally similar texts are actually at different levels of abstraction. Maybe this should be identified as a "force" driving the texts apart. -- DaveHarris

This depends on the support from the language! With adequate support, you must be able to specialize in a separate scope, thus not dealing with different levels of abstractions in the same place.

What OnceAndOnlyOnce requires in addition is version control support: the locality is defined at the level of the element, not at that of any version.

OnceAndOnlyOnce is a maxim or principle written in the form of a pattern. As such it is subject to much opinion and disagreement. There are, however, a number of patterns that embody the principle ...

On the other hand, the way you use these techniques is similar. It is hard to tell whether two things are similar or not. I usually discover similarity after the fact, i.e. it is easier to tell that two methods are similar after I write them than before. So, I tend to look at code I write and say "I've seen that before!" and then try to figure out where. When I find similarities, rewrite to make sure that I write something OnceAndOnlyOnce. This is the same whether I am writing a method or a metalevel architecture. -- RalphJohnson


CanOnceAndOnlyOnceLoop?


CategoryExtremeProgramming


EditText of this page (last edited June 18, 2004)
FindPage by browsing or searching

This page mirrored in WikiPagesAboutRefactoring as of July 17, 2004