revJournal - Features

Dan Shafer on Revolution and OOP, Part I

Dan Shafer returns to revJournal with an exclusive two-part article comparing traditional Object-Oriented Programming with Object-Like Programming in Revolution. In Part I, Dan explores and explains the basics of traditional OOP. Don't miss it!

Publisher's Note: As many of you are aware, Dan Shafer has launched his own online Revolution resource at [url=www.revolutionpros.com] Revolution Pros[/url], and has just published Volume One of his three-volume Revolution masterwork, "Revolution: Software at the Speed of Thought." Here, however, is a revJournal exclusive: the following two-part series is based on material that didn't make it into Dan's sensational books. Think of them as deleted scenes and outtakes that didn't, for whatever reasons, make it into Dan's final cut. Read and enjoy -- and if you haven't already done so, jump on over to Dan's Book Page and check out the trove of treasures that actually DID make it into the books! You won't be sorry...

Overview

In this two-part article, you will learn:
  • the important role being played in software development by concepts grouped under the rubric "Object-Oriented Programming" (OOP)
  • how Runtime Revolution parallels some of those concepts and goes its own way in others
  • how an understanding of OOP can help you be a better Transcript programmer

Runtime Revolution: Object-Like Programming

Let me be clear at the outset of this discussion: Transcript is not object-oriented programming in the "traditional" sense. I know it lacks some essential features of true OOP. But my interest in this article is how closely some key ideas in Runtime Revolution resemble those in OOP. The objective is to see what the world of OOP has to offer would-be Transcript gurus.

To describe Transcript and its somewhat loose ties to OOP, I have adopted the phrase Object-Like Programming. Transcript is object-like in that it uses some of the same terminology, adopts some of the same methods and adapts others, and in many ways looks and "feels" like OOP.

Before you can appreciate the validity and utility of all this, though, you need a basic understanding of OOP. The next section presents some of the fundamental ideas in OOP, but it is not an exhaustive treatment of the subject. If you are already familiar with OOP, you might want to skim or skip the next section.

OOP Fundamentals

Object-oriented programming is a way of looking at programming tasks that differs from the traditional approach. In procedural programming with C and other similar languages, you describe functions and procedures that operate on certain types of data. The data is separate from the functions that operate on it. In OOP, data and procedures that operate on the data are together, packaged in something called an object.

There are five central ideas in OOP: objects, messages, methods, classes, and inheritance. Although we explain each of these ideas briefly, they are so intertwined that an understanding of each depends on an understanding of the others.

What are objects?

Viewed abstractly, an object is a single programming entity that combines data with the procedures or functions that operate on that data. Viewed from a programming standpoint, objects are the elements of an OOP system that send and receive messages. I discuss messages in greater detail in the next section.

If you write a procedure to invert something in Pascal, you have to know in advance what kind of data the procedure will operate on. For example, inverting text might mean changing it from black letters on a white background to white letters on a black background. Inverting a matrix, however, is a complex mathematical operation unrelated to text color display. Similarly, inverting a graphic object like a pyramid is different from inverting text or numeric matrices. If you want a program to be able to invert any of these types of data, you would write a separately named procedure for each type of data, check in your program for the type of data to be manipulated, and then call the appropriate procedure. This process is depicted in Figure 2-1.

PROCEDURE invertjext
PROCEDURE invert_pyramid
Some text to be inverted
PROCEDURE invert matrix
I 9 8 4 3 87 2.04
II 240.1 009.0 -9.0031.25158
PROGRAM do_something CASE datajype of
text
invert_text
matrix
invert_matrix
pyramid
invert_pyramid
Figure 2-1. Data, procedures, and programs are separate in traditional programming

Object-oriented programming, however, permits the designer to say, in essence, "I want to invert whatever object I?m working with, so I'll just use an invert command and let the system take care of the problem." In OOP parlance, this command is referred to as a message. An object called, for example, matrix receives a message called invert and carries out its own processing in response to the message. There are still three separate invert routines in the program, but the part of the program that inverts an object doesn't need to be aware of them. This situation is represented in Figure 2-2.

You can probably see at least one big advantage to the OOP approach. If you want to add a new type of object to a procedural language application?for example, a list of items where invert means "reverse the order of"?you have to define a new procedure and add a new case to the main program. In other words, everything will change. Thanks to the well-known ripple effect, the consequences of this could take a long time to resolve if a bug gets introduced in the process. In an OOP world, though, you simply create a new object and add to it the ability to invert itself. Any other objects that send this new object an invert message do not need to be modified. The change is isolated and, therefore, manageable.

Object:Matrlx
I 9 8 4 3 87 2.04
II 240.1 009.0 -9.0031.25158
Method: Invert Method: Other(s)
invert message
Object: Pyramid
Method: Invert Method: Other(s)
Object: ProceMor-1
Object: Text
Some text to be inverted
Method: Invert Method: Other(s)
invert message
Need to invert an object
invert message

Figure 2-2. Data, messages, and methods in OOP

What are messages?

I have spoken glibly of messages as if it were obvious what they are and what they do. Although they may constitute a new programming idea, the concept of messages is not novel. When you call a friend across town and he or she answers the phone, you are sending messages. When you mail a letter to someone and the person on the other end opens it and reads it, you're sending messages. In fact, you probably do most of your work by sending messages of one kind or another to other people and to machinery or computers.

A message in the OOP world corresponds to a procedure or function call in a procedural language. Everything in OOP is accomplished only one way: One object sends a message to another object and the receiving object reacts. There are no alternate ways to get things done. The simple elegance of this model makes programs written for an OOP environment potentially easy to understand.

What are methods?

The idea of a method is the easiest of the five basic OOP concepts to explain. A method corresponds almost exactly to a function or a procedure. A method is the code contained in an object that tells the object how to react when it receives a message with the same name as the method.

In the previous example, each type of object had an invert method. When an object receives an invert message from another object, it simply carries out the instructions in that method. Sometimes, it sends a message back to the sending object indicating it has completed the instruction. Other times, it might trigger another method in another object, perhaps even a different invert method in another object, to accomplish its goals. To do so, it sends a message to that object.

If a message is sent to an object that does not have a method of that name defined, the system generally handles the problem with an error message such as "Object pyramid doesn't understand how to invert." Objects in OOP can be designed to understand and respond to any theoretically large number of methods.

What are classes?

Groups of objects with sets of common characteristics are called classes. The most important thing objects in a class have in common is the way they react to messages. If we had to write the same method for every single object, some of the advantages of OOP discussed in the next section would be lost in a mass of code. But if we define a class, each object we create as an instance, or example, of that class will already know how to behave in response to the messages the class contains.

The class, like everything else in an object-oriented world, is itself an object. Individual objects are referred to as instances of a class. Because a class is also an object, an object can be both a class and an instance of another class. The concept that makes classes significant is the fifth central OOP idea: inheritance.

What is inheritance?

In a true object-oriented world, objects inherit behavior from their ancestors in an ever-expanding and descending chain of heredity. All objects in OOP have at least one ancestor. The closer an object is to the root object class from which all other objects and classes spring, the fewer ancestors it has. This structure resembles an outline or a classification scheme.

Figure 2-3 depicts a classification structure for a class called Furniture. As you can see, this class has subclasses called Seating, Table, and Lamp. The subclass Seating, in turn, has other subclasses, and so on.

The key idea in inheritance is that if the class Furniture has a method called, for example, movelt, every member of every subclass can use that method in the same way without any special code in the subclass. In other words, if you send the message movelt to a love seat, the love seat object need not have a method called movelt. It simply passes the message up the hierarchy to its immediate ancestor (in this case, Sofa), which reacts if it has a method named movelt or passes the message on if it doesn't have a corresponding method.

Class: Furniture
Class: Seating
Class: Chair
Instance: Instance: Instance: Class: Stool Instance: Instance: Instance:
Class: Sofa Instance: Instance: Instance:
Class: Table
Class: Lamp
armchair easy chair secretarial chair
milking stool
bar stool
snack counter stool
sofa bed sofa love seat

Figure 2-3. Typical classification scheme

Generally, you can ?override? a method defined in a class so that an individual instance can react differently to that message. If you find yourself doing this too often, the method may be one that isn't really a good one around which to build a class.

Object-oriented programming summary

Let's see if we can summarize this sketchy look at object-oriented programming. Everything in an OOP environment is an object. Each object (except the one central object from which all others are descended) has at least one ancestor. An object inherits methods from all its ancestors in the chain that tell it how to respond to messages. Everything in an OOP environment is accomplished by objects sending messages to other objects.

It really is just that simple.

Why Object-Oriented Programming?

Why has OOP become such an important idea in the past few years? It really seems to be just a new way of looking at programs and data. So what's all the excitement about?

The characteristics inherent in OOP create numerous advantages in soft-ware design and development. Let's take a look at the three main ones often singled out by proponents of the OOP approach to computer programming. These are:

  • the natural "feel" of the OOP model of the problem
  • the high degree of code reusability
  • the ease of maintenance and modification


OOP is "natural"

The world in which we live is composed of objects. And as we saw earlier, we accomplish much of what we do by sending messages to other objects in our world and reacting to their messages. Furthermore, we generally do things by telling other objects what we want done rather than by explaining in great detail how to do it. The how describes the procedure and is part of the proce-dural programming model. The what describes the task, the problem, and its solution in descriptive, or declarative, terms, and is part of the declarative programming model of which OOP is a prime example. When you give your computer a print message, you don't tell it, "Now I want you to take this document that I've just finished creating and analyze its bit map structure. Got it?" You just tell it to print and expect its behavior to follow.

Similarly, if you give an assignment to a subordinate, you generally say, "I need the quarterly objectives report on my desk by 3:00, Jim." You don't say, "Jim, I want you to sit down at your desk. Take out a piece of paper and a pencil. Now, put at the top of the paper...."

But these descriptions ? simplified for illustration ? are good summaries of the differences between procedural programming and OOP. The world just doesn't work procedurally. Consequently, it is much easier to write programs designed to emulate or simulate reality and intelligence in OOP environments than in more procedure-oriented environments.

Code reusability

If you can define one object that is usable in several different systems, you can move it from one system to another with great ease in an OOP environment. There is nothing new to declare in the second system, no data structures to worry about, no other objects or procedures to modify. Simply pick up the object from program A and plop it down in program B and run it.

Consequently, if a programmer is proficient in and comfortable with OOP design concepts, he or she spends a great deal of time building reusable tools and objects. After that, a large percentage of programming time is spent simply assembling the appropriate objects into new "worlds," or systems. This means OO programmers tend to spend comparatively little time reinventing wheels.

Ease of maintenance

As we saw earlier, the ripple effect that causes so many software maintenance headaches all but disappears in an OOP environment. If the object behaves in a certain way in system A, it is guaranteed to work the same way in system B. Debugging is effectively (though not totally) reduced to finding messages sent to inappropriate objects, messages sent with the wrong number of arguments, and missing or undefined objects and methods.

Join us next week for Part II of this article, in which we'll consider OOP in the context of what it all means to you, the Revolution developer.



Dan Shafer is the Revolution guru behind the Revolution Pros website, and the author of the 3-volume official third-party Revolution book, Revolution: Software at the Speed of Thought.

© 2005 Fourth World Media Corporation All rights reserved. Portions copyright by the original authors.