11.1.1 An incorrect, but useful overview
In most cases, you get enough information if you master the core types entities that model an object-oriented system. These are Namespace, Package, Class, Method, Attribute, and the relationships between them, namely Inheritance, Access and Invocation. The figure below provides an overview of these classes.
This is an incorrect overview from two points of view:
- It does not show all entities. For example, a Method has also a Parameters and LocalVariables.
- At places, it shows direct relationships when in reality they happen through inheritance. For example, the Access points to an Attribute, while in reality it points to a superclass (StructuralEntity).
However, while incorrect, this picture is also useful because for most practical purposes it is all you need. Let us go through it step by step.
There isn’t much to say about most of the picture. Most of it goes along the lines of mirroring code concepts. For example, classes have methods, and methods belong to classes. More worthy of being noticed is the use of explicit entities to model relationships. Thus, we have:
- Inheritance models as its names says object-oriented inheritance between two classes and: the subclass, and the superclass.
- Access denotes a connection between a behavioral entity (often a Method in object-oriented systems) and an structural entity (often an Attribute).
- Invocation is a connection between one source and one or more target behavioral entities (often Methods). There can be more than one target behavioral entity because in dynamic languages we cannot identify statically with 100% accuracy the target of an invocation. See Section 11.1.3 for more details.
Another point that often generates confusion is the presence of both Namespace and Package in the meta-model. These are similar entities, but they model different things. Namespaces have a semantic meaning in the language so they influence the unique name of the entity, while a Package are physical entities for packaging:
- In Smalltalk the two are explicitly different.
- In C++ we have explicit Namespaces, but not so explicit Packages. A C++ namespace has no other responsibility beside providing a lexical scope for the contained classes and funcions.
- In Java, we have both Namespace (what you define in your Java source), and Package (the folder structure), but they happen to overlap in naming (although one is with . and the other one is with /). As a consequence, people tend to see them as packages only. It is for this reason, that Java extractors map Java packages to FAMIX Namespaces. Some can also mirror the same information in terms of FAMIX Packages.
Please note the missing arrows on the associations. This is not a mistake. In FAMIX, all associations are bidirectional. Let us take an example. Given the model from our running example (see Chapter 3), we have:
aClass := model allClasses entityNamed: #'org::argouml::ui::Critic'.
aClass methods first parentType == aClass
"--> true"
In other words, we can navigate from a class to its methods and back using only unary methods. Furthermore, these relationships are cached in the entities, and thus the traversal works fast.
The reason for this mechanism is that we want to offer the possibility of traversing the model from any point to any point. This is particularly useful when we use the API as a query language.
naming convention for attributes