Applying Object-Oriented Concepts
to Traditional Languages

Many object-oriented concepts may be applied to development with traditional, functionally-oriented languages such as Fortran and C. Herein we will call such usage "F/OO", short for Functional Object-Oriented.

How F/OO Differs From Your Usual

Traditional programs usually follow the pattern "input - compute - output". Large programs are broken into parts (subroutines, procedures, etc.) based on functions to be performed, hence the term "functional decomposition".

By contrast, object-oriented software parts (objects, classes, etc.) represent things that need to be dealt with, rather than functions that need to be performed. It is this focus on things, or objects, that gives rise to the term "object-oriented." The resulting structure of an object-oriented program is completely different from that of a functionally decomposed program.

This difference can be illustrated by a simple example. Consider a small program that accepts two scalar values from the keyboard, combines them into a vector, and prints the result.

A functionally-written Fortran program for this task might look as follows:

Functional Program

An object-based program to do the same thing might look as follows:

Object-based Program

These examples illustrate the following differences between functionally-decomposed and object-based programs:

  1. The object-based program has more lines of code for the same job.
  2. The object-based program has lots of subroutines.
  3. The subroutines are grouped into "classes" named after objects.
  4. All the subroutine names consist of two parts.
  5. It is harder to find the main program.
  6. The main program consists almost entirely of subroutine calls.
  7. The object-based program will run slower due to the overhead of more subroutines.
  8. The object-based program uses global variables (i.e., COMMON).
  9. The object-based program is more complicated.
  10. The object-based program looks harder to write.

Based on the above comparision, object-based programs are bigger, slower, more complicated, and harder to write than functionally decomposed programs.

Object-oriented decomposition looks like a really dumb idea!

Why F/OO Around?

Given that most of the differences between object-oriented and functional programs spotlight the advantages of functional decomposition, why would anyone want to write a program any other way, especially object-oriented? What's the advantage?

There is one advantage, which can be simply stated:

Object-Oriented Programs are Easier to Maintain.

They are not easier to write. They are not faster. They are not smaller. But they are much more maintainable.

This advantage is not readily apparent from looking at the examples because it stems from subtle characteristics:

  1. OO uses lots of subroutines, but the subroutines are small.

    Small subroutines are easier to write, debug, and understand. Because they are easier to debug, they can be more reliable. Being easier to write helps the developer; being more reliable helps the user; being more understandable helps the maintainer.

  2. The classes are named after not just any objects, but objects needed to accomplish the task.

    Object-based classes add structure to the program. Also, the process of identifying the objects helps greatly in understanding the task to be accomplished, and how to accomplish it. Additional structure puts an additional burden on developers, but helps maintainers.

  3. The two parts of each subroutine name are the name of the object to which it belongs, followed by the name of an operation on the object.

    The subprogram naming scheme more clearly identifies the role of each subroutine, which helps maintainers.

  4. The "operation" part of each subroutine name reflects operations needed to accomplish the task.

    This is similar to functional decomposition, except the association of operations with objects serves to add even more structure to the program. As in the case of objects, additional structure puts an additional burden on developers, but helps maintainers.

  5. The main program consists mostly of subroutine calls because it plays the role of task "supervisor", not task "doer".

    Each subroutine call is an order to an underlying class to accomplish part of the task. Like any good supervisr, the main program only gives orders (calls subroutines) and does not do any of the task itself. Rather, the supervisor embodies knowledge of the steps needed to accomplish the task. Such "encapsulation of process knowledge" also helps maintainers.

  6. The main program is harder to find because supervisors are classes, too.

    In some object-oriented languages, such as Ada, the syntax does not even provide for main programs. Instead, there is the concept of dynamic (executable) classes. In Java, every class can be dynamic - and can contain a main method - for purposes such as unit testing. The potential benefits of dynamic classes are profound, especially to maintainers.

  7. There are global variables, but they are grouped by object and appear only in the subprograms of their own class.

    Here, the COMMON block is being used to restrict the visibility, or scope, of a class's data to only the subprograms of that class. For example, only the VECTOR_xxx subroutines can access the /VECTOR/ variable V(); the SCALAR_xxx subroutines know nothing of the existence of V(). This is a rather unconventional use of the Fortran COMMON, which is usually used to enhance visibility. Other languages have more explicit syntax for restricting the visibility of data to a single class, such as a PRIVATE statement. This form of data scope restriction is one way a language like Fortran can achieve information-hiding. Information-hiding is a tremendous aid to maintainers.

    NOTE: No information is being hidden from maintainers, or any person! The term applies only to visibility of data among code units.

  8. The interfaces to a class's subroutines are stable and never change.

    Here, "interface" means not only the calling protocol, but also the external behavior, of the class. Thus, classes should be designed such that future changes to the class are unlikely to alter either the way the class is invoked, or what the class does when invoked. We should strive to create classes so that only the way a class does what it does is likely to be changed.

    Interface stability combines with information-hiding to restrict the ripple effect of a change to only the class that is being changed. For example, say we change the VECTOR class to use two variables, V1 and V2, in place of the array V(2). This change does not alter the external behavior or the calling protocol of any of the VECTOR_xxx subroutines. Because the subroutine interfaces have not changed, and because no other class knows of the existence the /VECTOR/ variable V(), this change does not impact any class other than VECTOR.

    Restricting the ripple effect of change was the primary motivation behind the invention of object-oriented decomposition. Object-oriented development is attractive because it offers a solution to the long-standing problem of software maintenance. It is literally "development for maintenance" and is therefore a tremendous boon to maintainers.

  9. Object-based programs are more complicated and harder to write only if we retain our functional ways.

    We have already seen that object-oriented programs have more structure than functional programs. Increasing structure almost always decreases complexity. This will be true for most any non-trivial program (but perhaps not for our simple-minded example above). Decreased complexity helps both developers and maintainers.

    When suitable approaches are utilized, object-oriented programs can be easier to develop than functional ones. All object-oriented development methods use the same general process: (1) identify the objects, (2) design the classes, (3) implement the classes. Because each class is much smaller than the entire program, the development is broken down into small chunks which are individually easier to implement than the program. Because the total lines of code will generally be greater than in a functional program, however, the object-oriented development may take more time.

    OO has another characteristic which can be used to significantly reduce development time - well-designed classes are highly reusable. A suitable object-oriented development process coupled with a collection of reusable classes appropriate to the application can reduce development time to far below that achievable with functional methods, while gaining the maintainability benefits of object-oriented decomposition. The combination of object-based development methods and object-based reusable libraries is highly beneficial to developers as well as maintainers.

How F/OO Differs From "Real" OO

The term "object-oriented" (OO) is generally accepted to mean a method of software development based on the following concepts:
  1. Data abstraction
  2. Encapsulation and information-hiding
  3. Interface stability
  4. Objects
  5. Classes
  6. Composition
  7. Inheritance
  8. Polymorphism
  9. Dynamic binding
  10. Packages

The last of these concepts - packages - was introduced as recently as 1995 with the advent of Java. However, the period during which most of these concepts were developed (the 1970's and 1980's) was often fraught with debate as to to what constituted "object-oriented". Wegner helped resolve the issue by proposing the following taxonomy:

Because items 5-10 were largely the result of work on object-oriented programming languages (OOP), nearly everyone now assumes that the use of object-oriented principles requires a specialized, object-oriented language, and that traditional languages such as Fortran and C cannot be used for object-oriented development. However, items 1-4 were invented and tested during the 1970's using the languages then available. Thus, the assumption that an object-oriented language is required to apply these principles not entirely correct. Object-based development (using Wegner's definition), at least, can be achieved with traditional languages.

The persistence of this false assumption has had a detrimental effect on the adoption of object-oriented decomposition by the software industry. We have already seen how dissimilar object-oriented and functional decomposition are. Learning this new way of thinking, while at the same time learning the syntax and semantics of an entirely new programming language, can be formidable - especially to those well-schooled in the traditional approaches. Hence, much software is still written using functional decomposition, and the old software maintenance problems persist.

As we have seen, object-based (if not fully object-oriented) decomposition can be used with traditional languages. F/OO is the application of object-based (items 1-4) decomposition principles to the development of software written in traditional languages such as Fortran and C.

While not as elegant as development using an object-oriented language, F/OO is much more feasible for many developers because they can learn the most important concepts of object-oriented development while remaining within the familiar environment of a programming language they already know. Later, having mastered object-based concepts using F/OO, developers can learn the nuances of an object-oriented programming language much more easily.

When To F/OO Around

When should object-based decomposition be used?

Given that the purpose of object-oriented decomposition is to improve software maintainability, it follows that the longer a program is expected to be in service, the more it will benefit from being object-oriented, or even object-based. This is because a higher percentage of the money spent on such programs is spent on maintenance compared to initial development. Reducing the effort needed to maintain such programs can save significant amounts of money over the life of the program, even if the initial object-oriented development takes longer and costs more. Thus, object-oriented decomposition, rather than functional decomposition (FD), should be used for long-lived programs.

Given the decision to use object-oriented decomposition, when should one use F/OO instead of an object-oriented programming language (OOP)?

F/OO is the application of object-based principles to traditional programming languages. Thus, F/OO should be used if

  1. other considerations require the software to be developed using a traditional programming language, or

  2. the development personnel are unfamiliar or uncomfortable with object-oriented decomposition and object-oriented languages, but are highly experienced with traditional languages.

In either case, an additional benefit is that one's investment in traditional programming language tools and training can be retained while learning OO principles. F/OO spares the capital asset budget as well as the development personnel.

This decision logic may be summarized as follows:

Program
Lifespan
Development
Personnel
Language
Requirement
Recommended
Approach
long know OO traditional use F/OO
long know OO any use OOP (Java)
long don't know OO traditional use F/OO
long don't know OO any use F/OO or learn Java
short know OO traditional use F/OO or FD
short know OO any use OOP or FD
short don't know OO traditional use F/OO or FD
short don't know OO any use F/OO or FD


[home]
[OO] [Java] [memorial ships]
[humor] [income tax repeal]


Copyright (C) 1998 LDJ Trust