TweetFollow Us on Twitter

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.

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.


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;

PROCEDURE ParsePacket(thePacket:TDataType);
 IF NOT Form_Engine(thePacket) THEN
 IF NOT Chat_Engine(thePacket) THEN
 IF NOT Async_Engine(thePacket) THEN
 IF NOT File_Engine(thePacket) THEN
 IF NOT LogOn_Engine(thePacket) THEN
 IF NOT LogOff_Engine(thePacket) THEN

This piece of code just simply bothered me. It looks cumbersome and is difficult to manipulate. Each engine is always called, no matter whether or not the engine is on. There is no sense of which packet might effect what global data. Adding more engines to the code made the code segment even more awkward.

So I decided to apply a few of the techniques that I learned in Object Oriented Programming classes. I created some new data structures. These new structures included a new record type (TEngineRec), a pointer to this record (TEnginePtr) and a handle to the record (TEngineHdl). TEngineRec consisted of a TEngineHdl, a normal data Handle and a ProcPtr.


 EngineData: Handle;
 EngineProc: ProcPtr;
 NextEngine: TEngineHdl;
 TEnginePtr = ^TEngineRec;
 TEngineHdl = ^TEnginePtr;

For those unfamiliar with ProcPtr, it is a pointer to an actual procedure or function in memory. Depending on your language or development system, it allows the procedure it indicates to be invoked. To do the actual invoking of this procedure, I defined an Inline call that places the correct parameters on the stack and then jumps to the procedure the pointer is aimed at and executes it.

In order to make this code work, I also created one global variable, GEngineList, a TEngineHdl type.

VARGEngineList: TEngineHdl;

Obviously the idea was to try to create a linked list of Engines. GEngineList points to the first Engine in the list, and each engine points to the next one. A set of routines to add and subtract Engines to the the list was also needed. I therefore declare the following call.


FUNCTION AddEngine(theProc:ProcPtr;theData:Handle):TEngineHdl;

PROCEDURE RemoveEngine(theEngine:TEngineHdl);

These routines are uses to add and remove an engine from our list of active engines. The AddEngine call would be invoked like this:



theFormData :=...{Code to initilize data}...


Notice that when an engine was added, the pointer was passed to the Engine’s Packet_Handling routine. That routine will be executed later, when a packet comes in.

Now, let us revisit the original piece of code. The original code will pass a packet to all engines until it finds one that wants the packet. The new code only passes packets to engines that have been installed.


PROCEDURE New_ParsePacket(thePacket:TDataType);
 theList :=GEngineList;
 WHILE (NOT Handled) and (theList<>NIL) DO BEGIN
   IF Call_To_Proc(thePacket,theList^^.theData, theList^^.theProc)
 THEN Handled:=TRUE
 ELSE theList:=theList^^.NextEngine

Call_To_Proc is a glue routine that actually jumps to the Procedure pointed to at theList^^.theProc with thePacket and theList^^.theData as parameters.

Now, imagine what happens during a normal logon sequence. As a user first goes online, a LogOn Engine is created. Once the person is completely online, the LogOn Engine is removed and it’s handle and data handle are deallocated from memory. Then the Forms Engine and the Async engines are added to the Engine List. These Engines normally run for the life of an online session to handle most normal forms and asynchronous events.

At some point the user might decide to go to a Chat room. The Chat engine is added when, and only when, the user enters a Chat room. When he leaves the Chat room, the engine is removed. The same can happen to a File transfer engine.

Some of the advantages of this approach become apparent if you consider how we can use the new code to create new situations. Since the data for each engine is completely contained in that engines data handle, the protocol could be changed so that a user can be in more than one chat room at the same time. This would mean a chat room packet would have to have some information in it to determine whether it pertained to room “A” or room “B”, but that information would only require a couple of bytes of data and would be easy to include.

There is no reason why File transfer, or any other engine that could be conceived, could not be added and invoked any number of times, at any point in an online session. This gives us an amazingly powerful online asynchronous environment. What we are really seeing is an example of the Object Oriented concept of encapsulation of data and the concept of instance of an object.

More than one instance can easily be added to the code at any time. Until an instance is added, additional memory need not be allocated. If an engine is changed, or even if a new one is added, only routines related to the new engine need to be added. The parser code segment used to send a packet to the correct engine is never changed.

I have always considered Data Encapsulation and Instance of objects to be two of the three most important ideas associated with Object Oriented Programming. The third important idea is that of Inheritance. And this function of an Object Oriented Programming Language can be adopted to non-Object Oriented Programming Languages, too.

Actually we are already halfway there in our example. ProcPtrs can be manipulated so that certain data structures have pointers to some procedures, while other instances use other procedures. This simulates the idea that a method can be overridden or inherited. To see this more easily, lets consider another example that has ProcPtrs.

America Online has a very complete Forms engine that allows us to create almost any form using packets sent from the host. Each form packet has information describing windows and different fields on these windows. Different field types that can be on a window might include buttons, icons, pictures, non-editable text, editable text, lists, and so on. All the fields have certain tasks that they have to be able to perform. For example, each field must be able to be drawn, it must be able to handle a mousedown in it’s area, it must be able to be hilited, it must be able to handle a keystroke, it must be able to invert itself and it must have an action associated with it. Following this idea, a field data structure might look like this.


FieldRec = RECORD
  fArea : Rect;
  fActionNum : INTEGER;
  fText: Str255;
  fData : Handle;
  pMouseDown,pUpdate,pActivate,pHilite,pKeydown,pAction : ProcPtr;

FieldRec = ^ FieldPtr;
FieldHdl = ^FieldPtr;

Besides the data, a number of ProcPtrs are declared, one for each major task. Some of the tasks might be do nothing tasks. For instance, a non-editable text field would ignore keystrokes, or a picture would not need to have an action associated with it. Others are more specific for the given field type (the keystroke routine for an editable text field).

For example, when the window needs to be updated, the code might find the field list for that window. Then it would one by one cycle through each of the fields, invoking the draw command so that that portion of the window is drawn. That code would look something like the following example. Notice if the ProcPtr is nil, that means there is a do-nothing task, and it should be skipped.


PROCEDURE UpdateDisplay(theDisplay:DisplayHdl);
VAR theField:FieldHdl;
   IF theField^^.pUpdate<>NIL
   THEN Invoke_Update(theField,theField^^.pUpdate);

If a mousedown occurs, a similar scan is done. In that case, each field is checked to see if the mousedown occurs in it. The Mousedown ProcPtr will only be invoked if the mousedown has occurred in the relevant field. Notice that no matter which type of field is used, these pieces of code will never change.

Somewhere in the code, there will be a segment of code that creates these fields; this procedure is called New_Field. Each kind of field will have its own declaration section in the procedure. For example, a picture might look like this.


VAR theField:FieldHdl;
 kPicture: BEGIN

You can see that this kind field basically does nothing but draw itself. A more interesting kind of field might be a clickable Icon field.


 kClickIcon: BEGIN

This type of field has it’s own draw and invert calls. It also uses the Track_Invert call in order to handle a mousedown. That call keeps track of whether or not the mouse is inside the field area. It invokes the Invert ProcPtr repeatedly to hilite or unhilite the field depending on if the mouse is in or out of the area. If the user releases the button while the mouse is over the field, that call invokes the Action ProcPtr. The action ProcPtr is the most generic one, the Do_Action_Number procedure which does an action defined in the ActionNumber field.

If an entirely new kind of field needs to be created, say for example a clickable Picture, some of the previously defined routines could be used (inherited) to define this kind of object. This code would be added to the new field.


 kClickPict: BEGIN

We have created a new type of field, with it’s own specific appearance and function, without adding any new code except for the creation routine. Even if we had to create a new field with a new special task, (such as a new way to handle drawing,) only a single new procedure would need to be written (in this case, Draw_Bitmap_Icon). We can use the old procedures/tasks for the rest of the new field.

Notice that this Clickable PICT field is related to a non-Clickable PICT field. These fields don’t quite function as a superclass and a subclass, but there is a relationship involved. This might not be true inheritance, but it sure does make it easier to create new fields when they are needed.

Inheritance, instancing of objects and data encapsulation are possibly the three most important ideas in object oriented programming, and they have all been simulated in a non-object-oriented procedural language. And I would like to add that this this is not merely sample code that is never used in a real-world application. These three ideas are used over and over again inside of America Online.

The code would have never been designed the way it was if I had not aware of the object oriented concepts and had not seen them used in a object oriented world. America Online is a better product because of the object oriented lessons learned. The code is more flexible, easier to work with and more powerful. Even if a programmer is never to use MacApp in a major project, or he is never to use an Object Oriented Programming Language in a job, the project or job he is working on, the code he creates may be better if he uses the object oriented concepts he learns.


Community Search:
MacTech Search:

Software Updates via MacUpdate

Grab it now: Game Craft’s Legend of War...
The real time strategy game is now available for you to sink your teeth into, through the App Store and Google Play. Combining elements of skill, strategy and empire building, Legend of War is a real gamers’ game. [Read more] | Read more »
Skateboard Party 3 ft. Greg Lutzka (Gam...
Skateboard Party 3 ft. Greg Lutzka 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Skateboard Party is back! This third edition of the popular sports franchise features professional skater... | Read more »
Cubious (Games)
Cubious 1.0 Device: iOS Universal Category: Games Price: $.99, Version: 1.0 (iTunes) Description: Cubious – How smart are you? How high is your IQube? Solve the impossible puzzles to find out, and help a lost little cube find his... | Read more »
Goat Simulator Waste of Space (Games)
Goat Simulator Waste of Space 1.1 Device: iOS Universal Category: Games Price: $4.99, Version: 1.1 (iTunes) Description: ** IMPORTANT - SUPPORTED DEVICESiPhone 4S, iPad 2, iPod Touch 5 or better.** | Read more »
Wildfulness - Unwind in nature and calm...
Wildfulness - Unwind in nature and calm your mind with nature sounds and illustrations 1.0 Device: iOS Universal Category: Healthcare & Fitness Price: $1.99, Version: 1.0 (iTunes) Description: Spending time in nature helps you to... | Read more »
Dr. Panda Racers (Education)
Dr. Panda Racers 1.0 Device: iOS Universal Category: Education Price: $2.99, Version: 1.0 (iTunes) Description: STEP ON THE GAS, RACE AND WIN!Fasten your seat belts and get ready to race! Speed your way to the finish line while doing... | Read more »
ROMANCING SAGA 2 1.0.0 Device: iOS Universal Category: Games Price: $17.99, Version: 1.0.0 (iTunes) Description: Romancing SaGa 2, originally released only in Japan in 1993, has been completely remastered and now receives its first... | Read more »
WRIO Keyboard (Utilities)
WRIO Keyboard 1.0 Device: iOS iPhone Category: Utilities Price: $2.99, Version: 1.0 (iTunes) Description: 40% OFF DURING LIMITED INTRODUCTORY OFFER | Read more »
Hatoful Boyfriend (Games)
Hatoful Boyfriend 1.0 Device: iOS Universal Category: Games Price: $4.99, Version: 1.0 (iTunes) Description: The hit PC game that everybirdie loves has now migrated to your mobile device! Now you are free to explore the wonders of St... | Read more »
Warp Shift (Games)
Warp Shift 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: [ CHECK YOUR HARDWARE: Warp Shift does NOT run on iPhone 4, iPad 1 and iPod touch 4G or older devices! It requires at least iOS8... | Read more »

Price Scanner via

Goal Zero and OtterBox Partner to Expand iPh...
Goal Zero, specialists in portable power, have announced a partnership with OtterBox, brand smartphone case protection, to offer the Slide and Slide Plus Batteries as modules compatible with the new... Read more
15-inch Retina MacBook Pros on sale for up to...
B&H Photo has 15″ Retina MacBook Pros on sale for up to $210 off MSRP. Shipping is free, and B&H charges NY tax only: - 15″ 2.2GHz Retina MacBook Pro: $1799 $200 off MSRP - 15″ 2.5GHz Retina... Read more
Clearance 2015 13-inch MacBook Airs available...
B&H Photo has clearance 2015 13″ MacBook Airs available for $250 off original MSRP. Shipping is free, and B&H charges NY sales tax only: - 13″ 1.6GHz/4GB/128GB MacBook Air (MJVE2LL/A): $799... Read more
Apple refurbished Apple TVs available for up...
Apple has Certified Refurbished 32GB and 64GB Apple TVs available for up to $30 off the cost of new models. Apple’s standard one-year warranty is included with each model, and shipping is free: -... Read more
21-inch iMacs on sale for up to $120 off MSRP
B&H Photo has 21″ iMacs on sale for up to $120 off MSRP including free shipping plus NY sales tax only: - 21″ 3.1GHz iMac 4K: $1379.99 $120 off MSRP - 21″ 2.8GHz iMac: $1189 $110 off MSRP - 21″ 1... Read more
Kanex Introduces GoPower USB-C Rechargeable B...
Kanex has announced its GoPower USB-C portable battery for the USB-C MacBook, featuring the new industry standard connector and cable used for connectivity and power. Providing users with a new... Read more
Convertible and Detachable Devices Winning Ov...
According to the latest figures published by International Data Corporation (IDC), Western European shipments of ultraslim convertibles and detachables posted positive growth (44.7%) to account for... Read more
New MacBook Pros And Will MacBook Air Be Upgr...
With my mid-2013 13-inch MacBook Air closing on its third anniversary come November, I’m in system upgrade mode. Actually the Haswell CPU equipped Air is still doing a fine job, but my good wife is... Read more
Apple’s Education discount saves up to $300 o...
Purchase a new Mac or iPad using Apple’s Education Store and take up to $300 off MSRP. All teachers, students, and staff of any educational institution qualify for the discount. Shipping is free, and... Read more
13-inch 2.5GHz MacBook Pro on sale for $999,...
B&H Photo has the 13″ 2.5GHz MacBook Pro on sale for $999 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Read more

Jobs Board

Editor, *Apple* News - APPLE (United States...
Job Summary The Apple News team is looking for a passionate and knowledgeable editor with experience covering entertainment/pop culture and experience running social Read more
*Apple* Nissan Service Technicians - Apple A...
Apple Automotive is one of the fastest growing dealer...and it shows. Consider making the switch to the Apple Automotive Group today! At Apple Automotive , Read more
ISCS *Apple* ID Site Support Engineer - APP...
…position, we are looking for an individual who has experience supporting customers with Apple ID issues and enjoys this area of support. This person should be Read more
Automotive Sales Consultant - Apple Ford Linc...
…you. The best candidates are smart, technologically savvy and are customer focused. Apple Ford Lincoln Apple Valley is different, because: $30,000 annual salary Read more
*Apple* Support Technician II - Worldventure...
…global, fast growing member based travel company, is currently sourcing for an Apple Support Technician II to be based in our Plano headquarters. WorldVentures is Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.