Introduction to the SOMobjects Developer Toolkit

This section contains:

Background
Object-oriented programming(OOP) is an important new programming technology that offers expanded opportunities for software reuse and extensibility. Object-oriented programming shifts the emphasis of software development away from functional decomposition and toward the recognition of units (called objects) that encapsulate both code and data. As a result, programs become easier to maintain and enhance. Object-oriented programs are typically more impervious to the ripple effects of subsequent design changes than their non-object-oriented counterparts. This, in turn, leads to improvements in programmer productivity.

Despite its promise, penetration of object-oriented technology to major commercial software products has progressed slowly because of certain obstacles. This is particularly true of products that offer only a binary programming interface to their internal object classes (Example: products that do not allow access to source code).

The first obstacle that developers must confront is the choice of an object-oriented programming language.

So-called pure object-oriented language (such as Smalltalk) presume a complete run-time environment (sometimes known as a virtual machine), because their semantics represent a major departure from traditional, procedure-oriented system architectures. So long as the developer works within the supplied environment, everything works smoothly and consistently. When the need arises to interact with foreign environment, however (for example, to make an external procedure call), the pure-object paradigm ends, and objects must be reduced to data structures for external manipulation. Unfortunately, data structures do not retain the advantage that objects offer with regard to encapsulation and code reuse.

Hybrid languages such as C++ on the other hand, require less run-time support, but sometimes result in tight bindings between programs that implement objects (called "class libraries") and their clients (the programs that use them). That is, implementation detail is often unavoidably compiled into the client programs. Tight binding between class libraries and their clients means that client programs often must be recompiled whenever simple changes are made in the library. Furthermore, no binary standard exists for C++ objects, so the C++ class libraries produced by one C++ compiler cannot (in general) be used from C++ programs built with a different C++ compiler.

The second obstacle developers of object-oriented software must confront is that, because different object-oriented languages and toolkits embrace incompatible models of what objects are and how they work, software developed using a particular language or toolkit is naturally limited in scope. Classes implemented in one language cannot be readily used from another. A C++ programmer, for example, cannot easily use classes developed in Smalltalk, nor can a Smalltalk programmer make effective use of C++ classes. Object-oriented language and toolkit boundaries become, in effect, barriers to interoperability.

Ironically, no such barrier exists for ordinary procedure libraries. Software developers routinely construct procedure libraries that can be shared across a variety of languages, by adhering to standard linkage conventions. Object-oriented class libraries are inherently different in that no binary standards or conventions exist to derive a new class from an existing one, or even to invoke a method in a standard way. Procedure libraries also have the benefit that their implementations can be freely changed without requiring client programs to be recompiled, unlike the situation for C++ class libraries.

For developers who need to provide binary class libraries, these are serious obstacles. In an era of open systems and heterogeneous networking, a single-language solution is frequently not broad enough. Certainly, mandating a specific compiler from a specific vendor in order to use a class library might be grounds not to include the class library with an operating system or other general-purpose product.

The System Objects Model (SOM) is IBM's solution to these problems.

Introducing SOM and the SOMobjects Toolkit
The System Object Model (SOM) is a new object-oriented programming technology for building, packaging, and manipulating binary class libraries.


 * With SOM, class implementers describe the interface for a class of objects (names of the methods it supports, the return types, parameter types, and so forth) in a standard language called the Interface Definition Language (IDL).


 * They then implement methods in their preferred programming language (which may be either an object-oriented programming language or a procedural language such as C).

This means that programmers can begin using SOM quickly, and also extends the advantages of OOP to programmers who use non-object-oriented programming languages.

A principal benefit of using SOM is that SOM accommodates changes in implementation details and even in certain facets of a class ' interface, without breaking the binary interface to a class library and without requiring recompilation of client programs. As a rule of thumb, if changes to a SOM class do not require source-code changes in client programs, then those client programs will not need to be recompiled. This is not true of many object-oriented languages, and it is one of the chief benefits of using SOM. For instance, SOM classes can undergo structural changes such as the following, yet retain full backward, binary compatibility:


 * Adding new methods,
 * Changing the size of an object by adding or deleting instance variables,
 * Inserting new parent (base) classes above a class in the inheritance hierarchy, and
 * Relocating methods upward in the class hierarchy.

In short, implementers can make the typical kinds of changes to an implementation and its interfaces that evolving software systems experience over time.

Unlike the object models found in formal object-oriented programming languages, SOM is language-neutral. It preserves the key OOP characteristics of encapsulation, inheritance, and polymorphism, without requiring that the user of a SOM class and the implementer of a SOM class use the same programming language. SOM is said to be language-neutral for four reasons:


 * All SOM interactions consist of standard procedure calls. On systems that have a standard linkage convention for system calls, SOM interactions conform to those conventions. Thus, most programming languages that can make external procedure calls can use SOM.


 * The form of the SOM Application Programming Interface, or API (the way that programmers invoke methods, create objects, and so on) can vary widely from language to language, as a benefit of the SOM bindings. Bindings are a set of macros and procedure calls that make implementing and using SOM classes more convenient by tailoring the interface to a particular programming language.


 * SOM supports several mechanisms for method resolution that can be readily mapped into the semantics of a wide range of object-oriented programming languages. Thus, SOM class libraries can be shared across object-oriented languages that have differing object models. A SOM object can potentially be accessed with three different forms of method resolution:


 * Offset resolution: roughly equivalent to the C++ virtual function concept. Offset resolution implies a static scheme for typing objects, with polymorphism based strictly on class derivation. It offers the best performance characteristics for SOM method resolution. Methods accessible through offset resolution are called static methods, because they are considered a fixed aspect of an object's interface.


 * Name-lookup resolution: similar to that employed by Objective-C and Smalltalk. Name resolution supports untyped (sometimes called dynamically typed) access to objects, with polymorphism based on the actual protocols that objects honor. Name resolution offers the opportunity to write code to manipulate objects with little or no awareness of the type or shape of the object when the code is compiled.


 * Dispatch-function resolution: a unique feature of SOM that permits method resolution based on arbitrary rules known only in the domain of the receiving object. Languages that require special entry or exit sequences or local objects that represent distributed object domains are good candidates for using dispatch-function resolution. This technique offers the highest degree of encapsulation for the implementation of an object, with some cost in performance.

SOM conforms fully with the Object Management Group's (OMG) Common Object Request Broker Architecture (CORBA) standards. (OMG is an industry consortium founded to advance the use of object technology in distributed, heterogeneous environments.) In particular,


 * Interface to SOM classes are described in CORBA's Interface Definition Language, IDL, and the entire SOMobjects Toolkit supports all CORBA-defined data types.


 * The SOM bindings for the C language are compatible with the C bindings prescribed by CORBA.


 * All information about the interface to a SOM class is available at run time through a CORBA-defined Interface Repository.

SOM is not intended to replace existing object-oriented languages. Rather, it is intended to complement them so that application programs written in different programming languages can share common SOM class libraries. For example, SOM can be used with C++ to do the following:


 * Provide upwardly compatible class libraries, so that when a new version of a SOM class is released, client code needn't be recompiled, so long as no changes to the client's source code are required.
 * Allow other language users (and other C++ compiler users) to use SOM classes implemented in C++.
 * Allow C++ programs to use SOM classes implemented using other languages.
 * Allow other language users to implement SOM classes derived from SOM classes implemented in C++.
 * Allow C++ programmers to implement SOM classes derived from SOM classes implemented using other languages.
 * Allow encapsulation (implementation hiding) so that SOM class libraries can be shared without exposing private instance variables and methods.
 * Allow dynamic (run-time) method resolution in addition to static (compile-time) method resolution (on SOM objects).
 * Allow information about classes to be obtained and updated at run time. (C++ classes are compile-time structures that have no properties at run time.)

The SOM Compiler
The SOMobjects Toolkit contains a tool called the SOM Compiler that enables implementers to build classes in which interface and implementation are decoupled. The SOM Compiler reads the IDL definition of a class interface and generates:


 * an implementation skeleton for the class,
 * bindings for implementers, and
 * bindings for client programs.

Bindings are language-specific macros and procedures that make implementing and using SOM classes more convenient. These bindings offer a convenient interface to SOM that is tailored to a particular programming language. For instance, C programmers can invoke methods in the same way they make ordinary procedure calls. The C++ bindings wrap SOM objects as C++ objects, so that C++ programmers can invoke methods on SOM objects in the same way they invoke methods on C++ objects. In addition, SOM objects receive full C++ typechecking, just as C++ objects do. Currently, the SOM Compiler can generate both C and C++ language bindings for a class. The C and C++ bindings will work with a variety of commercial products available from IBM and others. Vendors of other programming languages may also offer SOM bindings. Check with your language vendor about possible SOM support.

The SOM Run-Time Library
In addition to the SOM Compiler, SOM includes a run-time library. This library provides, among other things, a set of classes, methods, and procedures used to create object and invoke methods on them. The library allows any programming language to use SOM classes (classes developed using SOM) if that language can:


 * Call external procedures,
 * Store a pointer to a procedure and subsequently invoke that procedure, and
 * Map IDL types onto the programming language's native types.

Thus, the user of a SOM class and the implementer of a SOM class needn't use the same programming language, and neither is required to use an object-oriented language. The independence of client language and implementation language also extends to subclassing: a SOM class can be derived from other SOM classes, and the subclass may or may not be implemented in the same language as the parent class(es). Moreover, SOM's run-time environment allows applications to access information about classes dynamically (at run time).

Frameworks in the SOMobjects Toolkit
In addition to SOM itself (the SOM compiler and the SOM run-time library), the SOMobjects Developer Toolkit also provides a set of frameworks (class libraries) that can be used in developing object-oriented applications. These include Distributed SOM, the Interface Repository Framework, and the Emitter Framework, and the Metaclass Framework, described below.

Note: The SOMobjects Base Toolkit, the core version of SOMobject shipped with this documentation, contains only Distributed SOM, the Interface Repository, and the Metaclass frameworks. The complete SOMobjects Developer Toolkit can be ordered from IBM by calling 1-800-342-6672 in the U.S. or 1-800-465-7999 in Canada. The part number is 10H9767 for the CD-ROM containing SOMobjects for the AIX, OS/2,and Windows 3.x platforms (including online documentation). SOMobjects manuals are available individually.

Distributed SOM
Distributed SOM (DSOM) allows application programs to access SOM objects across address spaces. That is, application programs can access objects in other processes. The location and implementation of the object are hidden from the client, and the client accesses the object as if local. The current release of DSOM supports distribution of objects among processes within a workstation.

Interface Repository Framework
The Interface Repository is a database, optionally created and maintained by the SOM Compiler, that holds all the information contained in the IDL description of a class of objects. The Interface Repository Framework consists of the 11 classes defined in the CORBA standard for accessing the Interface Repository. Thus, the Interface Repository Framework provides run-time access to all information contained in the IDL description of a class of objects. Type information is available as TypeCodes-a CORBA-defined way of encoding the complete description of any data type that can be constructed in IDL.

Metaclass Framework
Finally, the Metaclass Framework is a collection of SOM metaclasses that provide functionality that can be useful to SOM class designers for modifying the default semantics of method invocation and object creation. These metaclasses are described in The Metaclass Framework.

What's New in SOMobjects Version 2.1
Version 2.1 of the SOMobjects Developer Toolkit provides enhanced capabilities and improved performance for both SOM and DSOM. In addition, the Toolkit now includes support for DirectToSOM (DTS) C++ compilers. New metaclasses in the Metaclass Framework allow class implementors to define classes that automatically possess certain convenience facilities.

The enhancements provided with SOMobjects Version 2.1 are described in detail in the following sections.

General Enhancements
C++ programmers can use DirectToSOM (DTS) C++ compilers (available from independent software vendors) as an alternative to the SOMobjects Toolkit's C++ bindings. (A DTS C++ compiler uses SOM classes to implement C++ objects.) The support provided by SOMobjects for DTS C++ consists of various enhancements to the SOM API (useful to SOM programmers in general), and a new emitter that produces DTS C++ header files corresponding to SOM IDL. DTS C++ programs include ".hh" header files, which are emitted as described in Generating binding files.

SOMobjects Enhancements
A new default process enables SOMobjects to initialize and destroy objects more efficiently (using the somDefaultInit and somDestruct methods).

A new kind of method is supported, nonstatic, that is similar to a C++ nonstatic member function. It is normally invoked using offset resolution but can use any form of SOMobjects method resolution. For more information, see a description of the nonstatic modifier in Modifier statements.

A new kind of data, staticdata, is supported that is similar to C++ static data members. A staticdata variable is not stored in an object; rather, the ClassData structure of the implementing class contains a pointer to the variable. For a description, see Modifier statements.

Two new modifiers, somallocateand somdeallocate, can be used to indicate that a user-written procedure should be executed to allocate or deallocate memory for class instances when the somAllocate or somDeallocate method is invoked. For descriptions of these modifiers, see Modifier statements.

The capability to cast objects is added. See the methods somCastObj and somResetObj.

Support is provided for loading and unloading class libraries. This was first introduced in SOMobjects for Windows 3.x and is now available for Windows NT and Windows 95. See the SOM_ClassLibrary macro in the SOM Programming Reference.

DSOM Enhancements
New SOM IDL modifiers are provided for memory management of parameters: memory_management= corba, caller_owns_parameters, caller_owns_result, object_owns_parameters, and object_owns_result. The individual modifiers are described in Modifier statements. For information about memory management, see Memory management. This memory-management support also includes the new method somdReleaseResources and the functions somdExceptionFree and SOMD_NoORBfree, described in the SOM Programming Reference.

Support is added for the CORBA constant OBJECT_NIL. In addition, the is_nil method of SOMDObject can now be used for local objects as well as NULL pointers.

Support is added for passing self-referential structs and unions (those valid in IDL) in remote method calls.

Support is added for local/remote transparency in DSOM's object-destruction methods. See "Destroying remote objects."

Users can now define customized base proxy classes. See "Customizing the default base proxy class."

Users can now specify an upper limit on the number of threads that a server can spawn, using the SOMDNUMTHREADS environment variable. See this variable under "Preparing the environment."

Improvements have been made in error handling and performance.

Additional sample programs are available with the SOMobjects Toolkit.

Metaclass Framework
A SOMMBeforeAfter metaclass enables the programming of "before/after" metaclasses, whose instances execute a particular method before and after each method invocation. See The Metaclass Framework for information about the new Metaclass Framework. Individual metaclasses, along with related classes and methods, are documented in the SOM Programming Reference.

A utility metaclass-SOMMTraced-is provided for tracing.

New Restrictions and Deprecated Methods
While implementing the Metaclass Framework, IBM learned that metaclasses must be programmed so that the capabilities they implement will be preserved when various metaclasses are combined (using multiple inheritance) into a SOM-derived metaclass. To assure this result, the Metaclass Framework metaclasses have been programmed using a Cooperative Metaclass. However, IBM is not yet ready to include the Cooperative Metaclass among the officially supported features of SOMobjects.

To prevent user-defined metaclasses from interfering with the operation of the Cooperative Metaclass and consequently with the Metaclass Framework, SOMobjects programmers are strongly urged to observe the following restriction when programming new metaclasses:


 * User-defined metaclasses can introduce new class methods and class variables, but should not override any of the methods introduced by the SOMClass class.

SOMobjects users whose metaclass programming requirements cannot be met within the above restrictions will be given access to the Cooperative Metaclass and its documentation. Note, however, that metaclasses developed using the Cooperative Metaclass may require reprogramming when an officially supported Cooperative Metaclass is later introduced.

In addition, use of a number of (public) methods introduced by SOMClass is now deprecated because they are useful only from overridden SOMClass methods. These methods are listed under the heading "Deprecated methods" in the documentation for SOMClass within the SOM Programming Reference, until such time as SOMobjects is ready to officially provide a framework within which their use will not interfere with the internal operation of SOMobjects itself.

The aforementioned deprecated methods are not available in the Windows NT/95 Version of SOMObjects.