Object Without Classes

Singleton and Component Package Patterns


Software Pattern Series



Transframe supports the Singleton and Component Packages pattern directly through its object construct, which integrates the singleton construct and the module construct from other object oriented programming languages.

Compared to Modula-3's module, Ada's package, Transframe's object is a more than module construct in terms of the following aspects:

The object construct is similar to a class construct, except that it starts with the keyword object and cannot be abstract (i.e. leaving class parameters undetermined). Example:


    class Model3D is NamedHierarchicalNode
    {
	abstract class Object3D (...);
	class DirectionalLight is Object3D (...);
	class Cube is Object3D (...);
	class Cylinder is Object3D (...);
	class Separator is Model3D (...);
	...
    };

    object OpenGLModel is Model3D  // OpenGL implementation
    {
	Object3D DirectionalLight (...) { //openGL implentation overriding};
	...
	enter ()  // constructor
	{
	    // creating openGL 3D device context here
	}
	exit ()  // destructor
	{
	    // destroying openGL 3D device context here
	}
    };

    object PexModel is Model3D  // Pex implementation
    {
	...
    };

Here we provided two implementations: both are instances of the Model3D class, which is an abstract class. Object construct overrides member classes declared in Model3D with implementation details. And they have constructors and destructors.

The advantage of this construct over the traditional definition/implementation module or package construct is the support of dynamic software composition. Consider:


    // an application using 3D models
    use Package3D;
    object My3DModelTest
    {
	enter ()
	{
	    with (GetSystemPackage3D())
	    {
		DirectionalLight (...);
		Cube (...);
		with (Separator(...))
		{
		    DirectionalLight (...);
		    Cude (...);
		    Cylinder (...);
		}
		DrawSelf();
	    }	
	}
    }

The function GetSystemPackage3D returns an object which implements the 3D model. The object could be loaded dynamically depending on the underlying operating system and the available implemented package in the form of a dynamic linking library.

Also, please pay attention to the power of recursive composition as shown in the member class Separator. By inheriting its enclosing class, the class Separater get a member class of itself, this enables an unlimited nested structure as show below:


	with (Separator(...))  // create a separator
	{
	     with (Separator(...))  // create a member separator 
	     {
	     	   with (Separator(...))  // create a member member separator 
		   {
			....
		   }
             }
	}

Nested objects are usually used for singletons, not for the purpose of packaging. Consider the following example:


    class ColorChoseFrame is ControlFrame
    {
	owner: AppDialogue;
	object ColorSpaceCube is Cube3D
	{
	    vertex_colors = ("black","red","yellow","green","cyan"...);
	    draw_style = DRAW_SMOOTH;
	    ...
 	    function GetColor():Color;
	}
	object ApplyButton is Button
	{
	    function WhenActivate()
	    {
		owner.Apply(ColorSpaceCube.GetColor());
	    }
	}
	...
    };

ColorSpaceCube and ApplyButton are singletons defined in the class ColorSettingFrame. They are both derived from existing classes. ApplyButton overrides the method WhenActivate defined in its base class. When a singleton is defined, an anonymous subclass of the singleton's base classes is implicitly defined; the singleton becomes the only instance of this anonymous subclass.

Transframe's object construct is also more than a Eiffel's singleton. It supports nested structures. Classes can be packaged within an object construct. The outmost object construct (free object) construct can be divided into a definition part and an implementation part. Consider another example:


     def object WindowsComponents  // a definition modlue (singleton)
     {
	 class Button is Window (name: char[], parent: Window, ...);
	 class ScrollBars is Window (name: char[], parent: Window, ...);
	 ...
     }
	 
     imp object WindowsComponents  // a implementation
     {
	 class Button is Window (name: char[], parent: Window, ...)
	 {
		// Win32 implementations
	 }
	 class ScrollBars is Window (name: char[], parent: Window, ...)
	 {
		// Win32 implementations
	 }
     }
	 
     imp object WindowsComponents  // an alternative implementation
     {
	 class Button is Window (name: char[], parent: Window, ...)
	 {
		// Motif implementations
	 }
	 class ScrollBars is Window (name: char[], parent: Window, ...)
	 {
		// Motif implementations
	 }
     }
	 

Classes are packaged with an object which serves as a package or module. The outmost singleton WindowsComponents is divided into two parts. Only classes that can be accessed from the outside are visible in the definition part. Multiple implementations can be provided. Software applications developed based on the definition interface are independent to the implementations.




- Copyright © 1997 Transframe Technology Corporation <info@transframe.com>
Last update: January 1997