Classes ​
This page covers details about the various kinds of classes that are used in ADOxx and how they can be created and modified to define a meta-model.
Class Basics ​
Classes are used in ADOxx to specify a template for their instances in models, defining their attributes, configuration and some formal semantics. They directly influence the syntax of the modelling language by explicitly stating what instances can be created in the models. The instances of classes are in general called objects, but some more specific names can also be encountered depending on the kind of class, like connector for instances of a relation class or row for instances of a record class.
Different kinds of classes are available in ADOxx. The kind of a class influences their semantics and the interaction with them and their instances in the modelling tool. The following statements are relevant for all kinds of classes, while specific details are described in the later sections:
- Classes have attributes which allow to specify properties for them and their instances.
- Classes use special attributes to configure some aspects of them and their instances, like their graphical representation, cardinalities etc.
- The name of a class must be shorter than 250 characters.
- Class names are case-sensitive, meaning that
Step
,step
andsTep
are considered distinct class names. - The names of classes of the same kind must be unique inside of a library. For example there can not be two classes with the name
Step
in the Dynamic Library.
- Class names are case-sensitive, meaning that
- Each class is internally identified by a unique integer number (its ID). This integer number is unique to an ADOxx installation, but it is not globally unique and can differ between ADOxx installations! For example the class
Step
of the same Dynamic Library can have different IDs on different computers. - Classes (except relation classes) inherit from other classes, arranging them in a class-hierarchy tree.
- Each class-hierarchy has exactly one class at its root whose name depends on their kind.
- Inheritance (super-class, sub-class) is transitive.
- A class has exactly one direct super-class (parent in the hierarchy), but inherits from all super-classes transitively (ancestors in the hierarchy).
- A class inherits attributes and semantics from its super-classes (ancestors in the hierarchy).
- A class can have multiple direct sub-classes (children in the hierarchy) and also multiple sub-classes transitively (descendants in the hierarchy).
- A class can be used in zero, one or several types of models.
- Objects are direct instances of exactly one class, but are considered to be an instance of that class and all of it's super-classes (ancestors).
The ADOxx platform also uses some predefined classes to handle certain functionalities.
(modelling) Classes ​
These are the basic classes that are instantiated as nodes in a model and have a graphical representation. They are only used in context of a specific model type and thus their instances always belong to a specific model.
When designing the class-hierarchy consider the functionalities provided through the predefined classes and the requirements for relation classes.
The root class is called __D-construct__
in the Dynamic Library and __S-construct__
in the Static Library. (modelling) Class instances are typically called modelling objects and are accessible in the Modelling Toolkit as part of a model.
Relation Classes ​
These are the classes which cover relations between instances of (modelling) classes and have a graphical representation. They are only used in context of a specific model type and thus their instances always belong to a specific model.
Every relation class must have specified exactly one from-class and one to-class chosen from the (modelling) classes. These restrict which types of modelling objects can be connected in the models. They do however consider inheritance between classes allowing to connect instances of the selected (modelling) class or any of its sub-classes, so it is important to build the class-hierarchy of (modelling) classes accordingly. Relation classes are also internally considered directed by the ADOxx platform, but it is up to the modelling languages whether to interpret them to be directed or not.
Unlike the other kinds of classes a relation class:
- Always has a graphical representation.
- Does not inherit from any other class.
- Does not use class attributes. Instead any special attributes are realized through instance attributes.
Relation classes do not have a root class, as they don't allow for inheritance. Their instances are typically called connectors. A connector must always connect exactly two modelling objects, having two endpoints (a source / from and a target / to) and are accessible in the Modelling Toolkit as part of a model.
Alternative: Inter-model references
An Inter-model reference type attribute (InterRef) can be used as an alternative to relating objects. These types of attributes also allow to reference a model from an object.
Record Classes ​
These classes are used for realizing complex attributes through record type attributes and describe the schema of a row. They are only used in context of a specific class together with an attribute and thus their instances always belong to a specific instance of a class in conjunction with that attribute.
The root class is called RecordClass
. Record class instances are typically called rows and are accessible in the Modelling Toolkit as part of an object's Notebook if it has been appropriately defined.
Attribute Profile Classes ​
These classes are used to create instances outside of models, providing a means to create a repository with instances that can be reused. Their instances can be either used on their own or can be referenced by objects through an Attribute Profile reference type attribute. This allows for consistency of the deposited information.
The root class is called AttributeProfileClass
. Attribute Profile class instances are typically called Attribute Profiles and are accessible through the Attribute Profile management component in the Development Toolkit and through the Edit -> Attribute profiles... menu of the Modelling component in the Modelling Toolkit.
Alternative: models as a repository
An alternative to using Attribute Profiles as instances in a repository is to define a model type whose models with their modelling objects represent the repository. In such a case linking to the objects happens through an Inter-model reference type attribute instead of an Attribute Profile reference type attribute.
Abstract Classes ​
An abstract class can not be directly instantiated. The opposite of an abstract class is called a concrete class. For an abstract class to be usable it is necessary to create a concrete class that inherits from them.
The use of abstract classes allows to define only a part of the syntax in the form of attributes and semantics to be reused while leaving out details that would be necessary for an actual instance. These details have to be provided by the concrete classes inheriting from the abstract class.
The special attribute ClassAbstract
is used to define a class as being abstract.
Container Classes ​
A (modelling) class can be specified to behave as a "container", meaning that its instances will be aware of other objects inside of them. This awareness is realized by automatically creating an Is inside
relation between the corresponding objects.
For a class to be considered a "container" it has to either inherit from one of the container sub-classes (__D_swimlane__
, __D_aggregation__
, __S_swimlane__
or __S_aggregation__
) or have a special class attribute __BehaveAsAggregation__
with its value set to 1
.
Some control over when an object is considered to be inside of another object is also available through the auto-connect
property of a model type.
Notation of a Class ​
Instances of (modelling) classes and relation classes are depicted in models using a graphical representation. The definition of this graphical representation is handled through the special attribute GraphRep
. In ADOxx the notation of these classes can be dynamic, adapting the drawn graphic to change based on the attribute values of the instances.
The notation of record classes and Attribute Profile classes is handled by specifying their Notebook structure. This is achieved through the special attribute AttrRep
.
Managing Classes ​
Managing and modifying classes is performed through the class-hierarchy dialog which is part of the Library management component of the Development Toolkit.
Any changes are only applied to the database after the library is saved.
Opening the Class-hierarchy ​
To access the class-hierarchy dialog select the Library management component. Once the component is active use the Libraries -> Settings menu or the Settings icon in the quick access bar. These open a separate pop-up dialog showing the available Application Libraries.
Select the library you want to manage the classes for and select the Class hierarchy... button to open another pop-up dialog showing the class hierarchy for that library. Depending on the selected library different classes can be managed:
- (modelling) Classes and relation classes in the Dynamic Library and Static Library.
- Record classes and Attribute Profile classes in the Application Library.
The following image shows the class-hierarchy for a Dynamic Library where the predefined sub-classes of the __D-construct__
root class are visible with the options Metamodel and Class hierarchy available under View turned on.
Caution
The (Metamodel)
shown next to some class names is an indicator that it is an ADOxx built-in predefined class. It is not part of their name.
Select the or icons next to the class names to expand or shrink the class-hierarchy, showing or hiding their sub-classes and attributes. The buttons on the right of the dialog allow to create, copy and delete classes.
Changes to the class-hierarchy can be saved by selecting the Save button or closing the class-hierarchy through the Close button. The ADOxx platform first performs some checks, informs about any possible issues via pop-up windows and at the end asks whether the changes should be saved to the database.
Creating a Class ​
For most kinds classes the following steps are necessary:
- Open the class-hierarchy where the class should be created.
- Select the View button and turn on the options Metamodel and Class hierarchy.
- Select the super-class from which the new class should inherit.
- Select the New -> New class... (label depends on allowed type of class) from the drop-down menu.
- Check that the super-class is correct, enter a name for the new class and select Ok.
For relation classes perform the following steps:
- Open the class-hierarchy where the class should be created.
- Select the View button and turn on the options Metamodel and Class hierarchy.
- Select the
Relation classes
entry or any other existing relation class. - Select the New -> New relationclass... from the drop-down menu.
- Select the allowed source class for from-class and target class for to-class. These consider inheritance of classes.
Note that the name of a class can not be changed after it has been created. As a workaround it is possible to create a copy of the class with a different name and then delete the class, but this also deletes all the instances of the class that were already existing.
Modifying a Class ​
The details of a class are handled through special attributes and their default values.
Copying a Class ​
- Open the class-hierarchy where the class should be copied.
- Select the View button and turn on the options Metamodel and Class hierarchy.
- Select the class to copy.
- Select the Copy... button.
- Select the super-class from where the new class copy should inherit.
- Check that the super-class is correct, enter a name for the copy and select Ok.
This only creates a copy of the class, but not its instances.
Deleting Classes ​
- Open the class-hierarchy where the classes should be deleted.
- Select the View button and turn on the options Metamodel and Class hierarchy.
- Select the classes to be deleted.
- Select the Delete button.
- If asked whether to really delete a class select Yes or Yes, all.
- This dialog only appears for classes that have been previously saved to the database.
Deleting a class also deletes all instances of the class.
Predefined Classes ​
ADOxx provides a set of predefined classes as part of the platform level. These classes are used in ADOxx to provide a specific semantic and basic syntax in the form of attributes which is then inherited by all sub-classes. Some of the functionalities provided by ADOxx are based on those predefined classes and passed on to classes inheriting from them.
Predefined Classes in Dynamic Library ​
The following lists the predefined abstract (modelling) classes according to their hierarchical structure as they appear in the Development Toolkit:
__D-construct__
: Super-class for all (modelling) classes of the meta-model, providing attributes necessary to use instances in a graphical model. This is the "root class" in the Dynamic Library's class-hierarchy.__D_event__
: Super-class that encapsulates concepts commonly encountered in graphs (for example a process) throughout which a state changes. Used together with the predefinedSubsequent
relation for the build-in simulation algorithms.__D_variable_assignment_object__
: Concepts that could change the state stored in__D_variable__
instances.__Neutral_element__
: Concepts which do not participate in executing a graph.__Start__
: Denotes the start of a graph.__Subgraph__
: Decomposition of a graph into a sub-graph to make complex models more readable. Technically a reference to another model.__Activity__
: A node in a graph that performs typical actions during the execution fo a graph.__Decision__
: Splits the path in a graph into several mutually exclusive alternative paths.__Parallelity__
: Starts one or several parallel paths in a graph that are later synchronized.__Merging__
: Synchronizes one or several parallel paths in a graph.
__D__end__
: Denotes the conclusion of a graph and finish state changes.
__D_variable__
: Stores a part of the state of the graph (relevant for the built-in simulation).__D_random_generator__
: Creates random figures that can be assigned to variables (relevant for the built-in simulation). Which variable to set is specified throughSets variable
connectors, while theSets
connectors specify at what point in the graph.__D_resource__
: Represents properties of graph nodes in its own class hierarchy. Descriptive properties need not only be defined as attributes of graph nodes, but can be described as classes using the class hierarchy from resources.__D_container__
: A super-class for the two predefined container classes.__D_swimlane__
: Denotes a container class with a rectangular shape that takes up either "rows" (entire horizontal width) or "columns" (entire vertical height) on the drawing area. The platform automatically determines for its instances which other instances are contained based on their position and explicitly denotes this by creatingIs inside
connectors between the instances.__D_aggregation__
: Denotes a container class with a rectangular shape that can be positioned freely. The platform automatically determines for its instances which other instances are contained based on their position and explicitly denotes this by creatingIs inside
connectors between the instances.
__D_agent__
: Represents a custom agent (relevant for the built-in simulation).__LibraryMetaData__
: Holds custom meta-data attributes for the library.__ModelTypeMetaData__
: Holds custom meta-data attributes for model types, like their graphical representation and model attributes.
Alternative: aggregation through special attribute
An alternative to inheriting from __D_aggregation__
for defining a class to be a container is to use the special attribute __BehaveAsAggregation__
.
Furthermore the following predefined relation classes are found in the Dynamic Library:
Is inside
: Relates parts to their container. Used mainly with__D_aggregation__
and__D_swimlane__
. Some control of when the connectors should be created is possible through theauto-connect
property of a model type in theModi
library attribute.Subsequent
: To specify the flow in a graph (for example a process), including possible forks due to the state of variables or probabilities. Relevant for the built-in simulation.Sets variable
: Connectors of this relation indicate what__D_variable__
should be set by a__D_random_generator__
.Sets
: Specifies at what point in the graph a__D_random_generator__
should be used to set a variable.Parameter
: Used withCall parameter
to link local variables from a graph to its sub-graphs. These connectors are attached to a__Start__
in the sub-graph to denote what variables should be passed to it.Call parameter
: Used withParameter
to link local variables from a graph to its sub-graphs. These connectors are attached to a__Subgraph__
in the graph to denote what local variables should be passed to the sub-graph.Uses
: Assigns to an__Activity__
the__D_resource__
s it uses.
The following example shows a graph and a possible mapping to the above abstract classes:
Predefined Classes in Static Library ​
The following lists the predefined abstract (modelling) classes according to their hierarchical structure as they appear in the Development Toolkit:
__S-construct__
: Super-class for all (modelling) classes of the meta-model, providing attributes necessary to use instances in a graphical model. This is the "root class" in the Static Library's class-hierarchy.__S_group__
: A super-class for representing nodes in a tree structure (relevant for the built-in simulation).__S_container__
: A super-class for the two predefined container classes.__S_swimlane__
: Denotes a container class whose rectangular shape that takes up either "rows" (entire horizontal width) or "columns" (entire vertical height) on the drawing area. The platform automatically determines for its instances which other instances are contained based on their position and explicitly denotes this by creatingIs inside
connectors between the instances.__S_aggregation__
: Denotes a container class with a rectangular shape that can be positioned freely. The platform automatically determines for its instances which other instances are contained based on their position and explicitly denotes this by creatingIs inside
connectors between the instances.
__S_person__
: Special super-class for representing persons to implement person dependent behavior (relevant for the built-in simulation).__S_resource__
: Represents properties of tree nodes in its own class hierarchy. Descriptive properties need not only be defined as attributes of tree nodes, but can be described as classes using the class hierarchy from resources.__S_agent__
: Represents a custom agent (relevant for the built-in simulation).
Alternative: aggregation through special attribute
An alternative to inheriting from __S_aggregation__
for defining a class to be a container is to use the special attribute __BehaveAsAggregation__
.
Furthermore the following predefined relation classes are found in the Static Library:
Is inside
: Relates parts to their container. Used mainly with__S_aggregation__
and__S_swimlane__
. Some control of when the connectors should be created is possible through theauto-connect
property of a model type in theModi
library attribute.
Best practices ​
- It is recommended to have the name of non-predefined abstract classes start and end with one underscore character (
_
). - Avoid starting or ending the names of classes with two underscore characters (
__
). These are used for predefined classes which are abstract and also by some special attributes. - Avoid using
(Metamodel)
as part of a class name. This is shown by ADOxx for some classes in the class-hierarchy next to the name to indicate the built-in predefined classes. - Avoid using the same name for two classes in the same library even if it is possible due to technicalities, like
Step
andstep
.- Provide some additional context to the name instead, for example in parentheses at the end of the name, like
Step (Process)
andStep (Staircase)
. - Avoid having two classes with the exact same name in different types of libraries (Dynamic Library, Static Library) without having a very good reason for it, for example to allow creating models that hold a repository of objects as part of the Static Library which are then referenced from models in the Dynamic Library.
- Provide some additional context to the name instead, for example in parentheses at the end of the name, like
- To identify a class rely on its name and the library it belongs, as the integer identifier (ID) can differ between installations.
- Consider using nouns as names for (modelling) classes and verbs as names for relation classes.
- Consider what you want to use from the built-in functionalities of ADOxx before transforming your conceptual class-hierarchy to the ADOxx predefined class-hierarchy. Some built-in functionalities (especially the built-in simulation) require the use of specific predefined classes and splitting classes between the Dynamic Library and Static Library.