Two very different O.O. worlds . . .

The Great Object Divide

Conrad Weisert
May 1, 2014

This article may be circulated freely as long as the copyright notice is included.

Two very different kinds

Textbooks and courses on the object paradigm often confuse inexperienced students by failing to distinguish between two very different object categories:

  1. application domain objects representing data items that are stored, processed, or maintained by application systems, and

  2. programming control objects that help to implement internal algorithms or flow-control structures.

They play entirely different roles in programming. Users of an application are usually acquainted with the former and understand their purpose and meaning. They are rarely concerned with the latter, which are of interest mainly to programmers.

Shifting emphasis

In the early days of object-oriented technology, emphasis was usually placed upon application domain objects. We learned OOP by designing and building classes for:

We learned Smalltalk and early C++ by focusing on such data. It was then a natural step to extend those techniques to:

But then we went on to more sophisticated program control structures that may represent no data in the application. It turned out that the O.O programming languages could support such structures that went far beyond the original O.O. concepts. Java, in particular, began to emphasize program control objects and ignore many application domain objects, probably because its reference object semantics are clumsy and inefficient for numeric data and other small (value) objects.

Seizing the opportunity

The more recent history of object-oriented programming continues this shifting emphasis. The O.O. emphasis in courses, textbooks, articles, and many applications has now shifted far toward control structures and away from application-domain data items!

Indeed, we find programmers routinely falling back on primitive types (double, int, etc.) for numeric types and simple string data for discrete types. This is especially a problem in Java, but it's spreading to C++ and C#, too.

When we question a programmer about his use of raw double for, say, a weight, he may reveal that he just never thought of using classes for those numeric data items! We can infer that the textbook and courses from which he learned OOP never thought of such practices either or at least failed to emphasize them.

Quasi primitives

The principle is slightly complicated by the existence of a few library classes that fill the role that built-in primitive types filled in other programming languages. Common examples are string and decimal.

"Well, what's wrong with this?" a puzzled neophyte programmer may ask:

   class  Employee  {
      string   name;
      decimal  salary;
         .
         .
    }

"After all, both name and salary are objects in that code, aren't they?" No, not really, unless the programmer intended that:

Experienced OOP practitioners know that we need two classes here: PersonName and Money. They must establish and enforce standard representations, prevent assignment of illegal values, and support (only) meaningful operations.

Quasi primitives fill roughly the same role in application programs as the built-in primitive data types. On their own they rarely yield bona fide objects with controlled behavior.


Last modified December 26, 2014 (minor format change)

Return to Home page.
Technical articles