Modeling for AndroMDA

AndroMDA is an automatic tool with a medium amount of intelligence built into it. Such a tool always has to rely upon some clearly defined preconditions; in the case of AndroMDA, these preconditions are modeling conventions. This means that a UML model for use with AndroMDA cannot be structured arbitrarily but has to adhere to a certain structure that can be interpreted by AndroMDA.

On the other hand, not too many constraints should be imposed on the modeler - after all, a model should represent the conceptual reality of the customer's requirements and the structure of the application domain.

To sum up it all up, we've tried to keep the number of rules low in order to keep your freedom of modeling high. Keep in mind: modeling standards/requirements will ultimately be dependantant on the implementation(s) of the cartridge(s) you employ at build time. Each cartridge has required properties and modeling conventions that must be followed. See Cartridges for more information. In general, there are rules to follow (seen below) when you start sketching a design model and you want AndroMDA to generate your components smoothly.

General Modeling Rules

Stereotypes drive code generation!: UML Stereotypes are a kind of "label" that you attach to modeling elements in order to classify them.

Please note that AndroMDA can now also generate code from templates based on properties of any model element found in the XMI, so theoretically it is possible to generate code without even using stereotypes.

Example: You tag a CustomerService class with a <<Service>> stereotype. AndroMDA sees this stereotype, looks into its internal dictionary of available code generation components (called "cartridges") and finds the EJB cartridge. In the EJB cartridge, two templates correspond to the <<Service>> stereotype: SessionBean.vsl and SessionBeanImpl.vsl. AndroMDA uses the internal representation of CustomerService loaded from the model, calls the processing engine twice, and two output files are generated: CustomerServiceBean.java and CustomerServiceBeanImpl.java.

A small model, containing an element tagged with the <<Service>> stereotype, can be seen in this picture:

images/CarRentalCustomers.gif

Even though modeling will depend primarily on how the cartridge is implemented. There are some standard ways of modeling which MUST be followed to ensure the model is syntactically and semantically complete, meaning the cartridge performing generation has enough information on which to generate from.

These are listed here.

  • Names: the general rule for all the names is to capitalize the first letter of each concatenated word (i.e exampleOfCapitalizationOfConcatenatedWords). This applies to all model element names (methods, operations, attributes, associations, association ends, etc.).
  • Specify the type of ALL attributes and operation parameters. Some tools with allow you to specify an attribute or operation without making you specify it's type, but make sure you specify this, as a cartridge performing generation will expect this information.
  • Specify visibility where visibiliy counts. Attributes on generated output are ALWAYS private, however, the accessor and mutator of each attribute will have the visibilty that you define in the model. For example: if you define the name attribute on your Person element to have a visibility of public, then the accessor and mutator for that element will be public as well, if you define the name attribute's visibility as private, then the accessor and mutator for attribute will be generated with a private visibility.
  • Specify the multiplicities of both ends of ALL associations. Cartridges use and require all multiplicity information.
  • Make sure names of association ends making up an association are UNIQUE within the association. If more than one association end of the same association is the same name, there will be conflicts from the generated output.
  • Do not leave unused elements dangling in your model. One of the biggest causes of syntatic incompleteness is the existence in the model of partially defined elements that are undetected by the modeler because they do not reside in any model diagram. Its easy to make the mistake of deleting the element from the diagram but then forgetting to delete it from the model as well.
  • If an element CANNOT exist without another element, define the association end of the owning element as composite aggregation. An association between a house and a room is a good example of composite aggregation. Destruction of the house implies destruction of all rooms that the house contains. Therefore the association end of the house to a room would be defined as composite aggregation (i.e. a black diamond).
  • Specify ordering where ordering matters. When using multivalued attributes and association ends you should be able to specify whether or not these are ordered in the modeling tool. Make sure you specify this if ordering does matter for these multivalued properties since cartridges need to be able to take advantage of this specification. For example, if an association end was defined as ordered, a cartridge generating to Java may specify the type as a java.util.Set instead of a java.util.Collection (if it was left unspecified or defined as unordered).
  • Do NOT add getter and setter operations for attributes. The cartridge will generate any required accessor and mutator operations needed at generation time.
  • Do NOT add getter and setter methods for association ends. The cartridge will generate any required accessor and mutator operations needed at generation time.
  • Define and use Datatypes for simple types. Use UML Datatypes for simple types such as String, Collection, Set, etc. instead of using the language specific types which the tool may implement by default (i.e. java.lang.String). You want to keep the model as language independent as possible. Cartridges use mapping files at generation time to map Datatypes to specific language types (i.e. for Java, these could be: Collection --> java.util.Collection, Blob --> java.sql.Blob, etc.)