OO and the Nodal Model

From Organic Design wiki
Revision as of 21:35, 12 December 2006 by Nad (talk | contribs) (Class-based programming and Prototype-based programming (intros from 'pedia))

The OOP methodology helps us to model our systems in terms of real objects and relationships. It is a methodology so it can be done in any programming language, not just the object-oriented-programming-languages (OOPL's). In fact OO was even around before programming languages under the name of abstract data types (ADT's) in maths.

A quick OOP refresher

Objects are containers of properties, the values of which form the objects' state. Also contained in the object are a set of methods which are functions designed to manipulate its state. The function names and the parameters they require form the interface of the object, through which all external interactions take place. This is called encapsulation and allows the internal workings of the object to be independent from programs which use it.

Different kinds of objects are defined by the names and types of properties and the interfaces (names and parameters) of their methods. This structural aspect of an object is its class. When objects come into being to be used by a program, they are created by effectively using the class as a template, creating a new "live" version of it in a specific context and under a specific name.

The way this template-like activity happens is via methods called a constructor and a destructor, which create and remove occurences of the class "in the field". Such an occurrence of a class is called an instance and the process of creating one is referred to as the class instantiating itself.

Often a new class needs to be created which is a refinement or extension of an existing class. This is called inheritance and we say that the new class is derived from the existing one. The new class is the sub-class or derived-class of the original one, and the original is the super-class or base-class of the new. Multiple-inheritance is when a class is derived from more than one base-class; it inherits the properties and methods from them all. (Note: multiple-inheritance is not the class-chain formed from classes to sub-classes, multiple inheritance means a class is actually derived from more than one chain. Today the only commonly known language supporting this is C++).

Polymorphism is when a base-class defines the interface for a method, but leaves it to the derived classes to implement the method. For example, a shape class may define the interface for an area method which all shapes must have, but the actual implementation (in this case a formula) depends on the specifics of the derived classes such as triangle or circle.

Classes

Class-based programming, or more commonly class-orientation, refers to the style of object-oriented programming in which inheritance is achieved by defining classes of objects, as opposed to the objects themselves (compare Prototype-based programming which is the nodal model's paradigm).

The most popular and developed model of OOP is a class-based model, as opposed to an object-based model. In this model, objects are entities that combine state (i.e., data), behavior (i.e., procedures, or methods) and object-identity (unique existence among all other objects). The structure and behavior of an object are defined by a class, which is a definition, or blueprint, of all objects of a specific type. An object must be explicitly created based on a class and an object thus created is considered to be an instance of that class. An object is similar to a data structure, with the addition of method pointers, member access control, and an implicit data member which locates instances of the class (i.e. actual objects of that class) in the class hierarchy (essential for runtime inheritance features).

Prototype-based programming

Prototype-based programming is a style of object-oriented programming in which classes are not present, and behaviour reuse (known as inheritance in class-based languages) is accomplished through a process of cloning existing objects which serve as prototypes. This model is also known as class-less, prototype-oriented, or instance-based programming.

The original (and most canonical) example of a prototype-based language is the programming language Self developed by David Ungar and Randall Smith. However, the class-less programming style has recently grown increasingly popular, and has been adopted for the programming languages JavaScript, Squeak when using the Viewer framework to manipulate Morphic components, Cecil, NewtonScript, Io, MOO, REBOL, Kevo, and several others.

OOP and Tree Structures

It's clear that the base class to derived class relationships tie the classes together into a tree structure. This structure is called the class tree or inheritance tree. These trees are referred to as models in UML because the interconnections between them can't usually be represented as a simple one-to-many tree. In this document we will just use tree which is synonymous with structure, hierarchy or model.

It was mentioned above that the running instances also formed trees. These could generally be called dynamic trees, but they've also often referred to as object models or runtime models. These instances also form a tree structure because the content of an instance are also instances, they're defined by the class in terms of classes, so there's a very strong connection between the two trees. On instantiation, the initial state structure is instantiated too. When an instance contains another instance like this, it's called the parent of the instance, and the contained instance is the child. All the instances in the same parent are siblings to each other.

So to summarise, we have two strongly related trees, a static tree of classes, and a dynamic tree of instances.

Beyond OOP

Here we'll take a closer look at some of the OO foundations to reveal some limitations which are no longer needed due to a more matured OO environment. Removing these limitations results in a simpler, yet more powerful model which is able to reflect the real-world concepts much more closely.

Multiple Inheritance

The dropping of multiple inheritance severely hinders a languages ability to mirror real world concepts at an architectural level. Unfortunately, reality is "messy" and concepts rarely have a single chain of inheritance. Even worse, the inheritance chain that a concept is considered to be derived from is often dependent on the context in which it's taken.

Multiple inheritance has been omitted from most modern languages because it's considered dangerous. But this and many other dangers are included in the nodal model, because it should be organisation at higher levels that maintain control, not deviation from the philosophy through patching on limitations at the lower levels!

So before moving on, lets first adjust our concept of a class to include multiple inheritance by saying that a class can have a list of base-class references like C++, not just a single reference. Perfect, that's much more of a mess; just like real life!

Unifying the Inheritance Tree

So now that we've sorted out what content a class inherits, what about the content it introduces of its own? What form does that take?

If all the content of objects is purely other objects, then some simplification can take place. Unfortunately current languages cannot take advantage of this, because methods are composed of the symbolic logic of their programming language. Also, data-types used for storing symbols, numbers and times etc. are not objects either and therefore require further syntax outside the inheritance-tree.

In the nodal model, absolutely everything is an object (called a node) right down to the binary level (even the two binary symbols are nodes). So the entire inheritance tree requires no specific syntax of its own, it's purely nodes containing other nodes. Don't worry about the apparent inefficiency of this, that's another job for higher level organisation discussed later.

So, back to the simplification. Our class defines its inherited content with an list of references to other classes, and the content it adds for itself is also a list of classes. And both lists operate the same way, by merging the content of the classes they reference into that of the class referencing them from its list. So we simply join the two lists into one, thereby saying that every classes' entire content structure is due to multiple inheritance. Many people refer to these two lists as isA relationships (class) and hasA relationships (content), but hasA is more general and flexible and really makes isA redundant.

Unifying Class and Instance

Remember we have two trees, a static class-hierarchy and dynamic runtime-tree. But classes and instances seem very similar, and the relationship between a base-class and its derived-class seems somehow very similar to that between a class and its instances. So why are they both totally separate entities? Why not have only nodes in the tree and have every node based on other nodes in the same tree?

When OOPL's first came about, classes were considered completely static, and instances were only as static as the running applications they were instantiated within. But these days, many instances need to be able to be completely persistent, and classes need to be able to change under the control of other applications. So such a unification of classes and instances is becoming very important.

We now have a single unified tree of nodes, which we'll call a nodal network rather than a tree because each node can be referred to from many places, and it's more characteristic of a network being global, persistent and distributed (more about that later).

The idea is that the processes and information are far more integrated with the architecture than in current OOP. This is because both the instances of applications as well as their models can be navigated and manipulated as a unified nodal network. The processes and information are all defined nodally, and these definitions are relative so they can be re-used throughout the network.

How the Nodal Model differs from OO

  • Naming: Many problems in OO come from its foundation in naming - all the classes and objects use textual-names as their fundamental means of identity and distinction leading to problems with naming conflicts and language-dependence.
  • Instance-based: Problems arrise in OO from the fundamental difference between class and instance...
  • Unified-space: Problems arrise in OO from the runtime space not being a logical continuation of the file-system and global network spaces
  • Self-organising: Change is inherent in the network, so applications within can execute directly from their conceptual description requiring less code
  • Self-contained: Like OO, the Nodal Model is a methodology and so can be implemented in any programming environment, but unlike OO, the Nodal Model fully describes its own instantiation into those enviornments.