OOP World
Volume Number: 7
Issue Number: 9
Column Tag: Developer's Forum
OOP in a non-OOP World
By Steve Sheets, Herndon, VA
[The following article was based on a presentation at the 1990 MacWorld
conference in Boston. The speech was given as part of a panel discussion on Object
Oriented Programming.]
OOP in a non-OOP World.
Object Oriented Programming.” These words congure up images of new
programming langauges like Smalltalk and C++. Visions of programmers everywhere,
throwing out their old compilers and sample code, and starting to program exclusively
in an Object Oriented Programming Language are called to mind. Jokes about those who
can only program in C or Pascal (“how many Pascal Programmer does it take...”)
begin to appear.
Time will tell if the above situations are more spoof than prediction. However,
the thinking that inspired them has a very specific fallacy that I would like to address.
First, let it be known that I am one of the world’s biggest fans of Object Oriented
Programming. I honestly believe that object oriented programming is likely to become
the next step in the evolution of programming languages. However, I do not agree that
this next step in programming style will be the exclusive domain of the new Object
Oriented Programming Langauges. This article intends to show how to make use of
object oriented techniques while programming in a non-object-oriented environment.
It is possible to use the ideas contained in Object Oriented Programming Languages
without using the traditional object oriented constructs like objects, classes,
inheritances, or methods. To understand how to go about using the techniques, but not
the items, a little history lesson is in order. Even though this lesson is on a slightly
different subject, it does have a point.
Back in the long ago, when Computers were first created and introduced to the
swarms of eager programmers, the majority of the programming languages were line
oriented. Languages like Basic and early versions of Fortran and Cobol usually
paralleled Assembly language, where almost every line of code did a specific task and
every line was followed by another line of code.
The flow of the program was usually from one line to another. The GOTO or
Conditional GOTO statements (or their equivalents) were used to control the flow by
branching, but in general, the flow was linear. This technique could cause problems.
For one thing, a programmer had to understand practically every single line of the code
before he could work with any piece of it. Otherwise, he would never know for sure if
the portion of the code he was modifying had an effect on some other line of code. If a
person were to try to work with code he had not created, he would likely have to spend a
great deal of time studying it before he could work with it.
A second, nastier problem with the linear flow arrangement became apparent as
programs became more complex. A simple piece of code might be modified again and
again, with different branches at many points in the code. Soon programmers started
getting Spaghetti Code, where the code was so complex, and the flow so strange, that no
one, perhaps not even the original programmer, could understand how the code worked.
the portion of the code he was modifying had an effect on some other line of code. If a
person were to try to work with code he had not created, he would likely have to spend a
great deal of time studying it before he could work with it.
To solve this problem, more Procedural oriented languages were introduced.
Languages like Pascal, C, and later expanded versions of line oriented languages were
given syntax and commands that allowed a programmer to divide the code into more
manageable procedures. People stated talking about the joys of this new Procedural
Programming style.
Now a interesting thing started happening. Programmers who used the
procedural languages, and who learned the joy of procedural programming, would
sometimes still have to program using the older languages. However, they had gotten
used to the advantages of the newer languages. So they added some of those new ideas to
their programs, even though they were using the old languages. They wrote the
programs so that they had separate subroutines and functions. Even Basic could be
written in this procedural style, once the programmer understood the concept.
Notice that just because a program is written in a good procedural base
programming language, it does not necessarily follow that the program is good code.
Some of the worst examples of spaghetti code have been written in the so called higher
level languages. These languages just made it easier to learn a new idea, like
procedural programming. The languages helped to teach programmers good
programming habits. Once the style was learned, it was not necessary to use the new
language or features in order to implement the technique.
That’s the end of the history lesson. Now, to come back to the present; nearly
everyone has been exclaiming the joys of these new Object Oriented Programming
Languages. Notice any possible parallel to my history lesson? Just like those who
years ago promoted Procedural Programming, they are right. There are many benefits
to using object oriented programming. This new type of programming will allow you to
code better. But you do not have to use Smalltalk or C++ or Object Pascal in order to
implement the benefits of object oriented programming.
Many programmers would probably like to use an object oriented approach, or at
least they would be interested in learning about it. However, these people may be
unable, for perfectly valid reasons, to start using an Object Oriented Programming
Language today. Many may have to work in a language specified by their company, or
one that is specified by their job contract. Some may have to work on a computer that
does not have a Object Oriented Programming Language. Or some might have to program
with co-workers who have not yet “seen the light” of Object Oriented Programming.
And many may have already invested a large amount of time and energy a piece of
non-object-oriented code, resources they might not have to reinvest in order to
convert over to an object oriented approach.
That last reason was the one that kept me from using an Object Oriented
Programming Language on my project, America Online. There was already an Alpha
version of the code written in Think Pascal, without Object extensions. Neither MacApp
or any other Object Oriented Programming Language was an option for America Online
when I came onto the project. While there is almost nothing left of the original Alpha
code in the current version of America Online, there never was a time when we could
take the time that would have been needed to convert the entire code to use Object Pascal
extensions or MacApp. So instead, what we did was to look at various parts of America
Online and decided what we could improve using what we had learned about America
Online.
Since I’m going to refer frequently to my project in this article, perhaps I’d
better give you a little information about it. For those who are not familiar with it,
America Online is a telecommunication service which connects our host mainframe to
personal computers using proprietary protocols and software. In my case, we are using
Macintoshes connected over a serial modem line. Using a low-level protocol, packets of
data are transferred, error free, from the host to the Mac or visa versa. When a data
packet comes in, the first few bytes of data designate what task that packet is intended
to preform. A group of tasks related to a specific online function is called an “Engine”.
Engines include the Form Engine (to create the windows), the Chat engine (to handle
online chat rooms), Async Engine (to handle other actions), File transfer engine (to
handle uploads & downloads), the LogOn Engine (to handle the log on process), and the
LogOff engine (which handles the log off process).
When a packet of information comes in from the Host, America Online has to
decide which engine handles that packet. Originally, America Online used procedural
styles. Each Engine had a Packet Handling routine that decided whether or not that
packet was handled by that engine. If it did, the packet was handled and the function
returned TRUE. If it did not, the function did nothing but return FALSE. Every engine
accessed the global variable space of the program in order to store states.
The original code segment that parsed a packet looked something like this.
{1}
FUNCTION Form_Engine(thePacket:TDataType); FORWARD;
FUNCTION Chat_Engine(thePacket:TDataType); FORWARD;
FUNCTION File_Engine(thePacket:TDataType); FORWARD;
FUNCTION LogOn_Engine(thePacket:TDataType); FORWARD;
FUNCTION LogOff_Engine(thePacket:TDataType); FORWARD;