Allow generation of instance diagrams
Originally reported on Google Code with ID 612
As a new generation target, allow generation of a 'random' instance diagram from any class model. Essentially the generator would walk the class diagram and generate an instance diagram that complies with the class diagram (with random numbers and strings for attributes) and links that conform to the multiplicity (Objects with 0, 1 and 2 where there is a * association for example)
The reason for this is to facilitate teaching. Each run of the generator would generate a different diagram.
See also issue 611, which proposes doing something similar with state machines.
Reported by @umple on 2014-07-24 14:27:19
This would require walking the class graph to determine possible starting points for creating instances, and generating random numbers of instances with random values for attributes that are consistent with association multiplicity (but perhaps with a little intelligence, e.g. if an attribute looks like a name, then generate human names)
The following is the first draft of a rough algorithm for creating randomized numbers of objects of each class.
You will have to consider many special cases:
- making sure it works with reflexive associations
- there may be runaway cases; it may be necessary to have a counter that stops adding new instances after, say 3 times the number of classes in the model.
Except for the two classes, this would all work within the generate method for the gvInstanceDiagram. However, the following blocks likely would be their own methods that would have to be passed necessary arguments.
Create a class UmpleInstance that you will use for each node, and which would have the following associations
- -> 1 UmpleClass; String [] attributeStrings;
Create a class UmpleLink that you will use for each arc
- -> 1 UmpleAssociation;
- -- 1 UmpleInstance fromInstance;
- -- 1 UmpleInstance toInstance;
Create the following data structures as a local variable of the generate method
// Objects that don't have all their associations yet ArrayList<UmpleInstance> partiallyCreatedObjectsQueue;
// a structure to allow us to quickly look up the list of instances of each class HashMap instanceMap key UmpleClass value List<UmpleInstance>
A. Loop through the classes in the model Add each to instanceMap with an initially empty list of UmpleInstance
B. Iterate through all keys of InstanceMap (i.e. through all classes) If the value is empty (no instances yet) then we need to find the next starting class from the ones that don't have instances: Tentatively mark the first such class as the starting class, but keep looking If any class is encountered with a 1-- association then that has priority, and pick the first of these, but keep looking; If any class is encountered that is singleton then use this as the starting class. If we get to the end and there are no classes without instances then we are done
C. With our starting class (that doesn't have any instances yet) Decide how many instances to randomly create. For a singleton it is always 1. Otherwise, with 50% probability 1; 33% probability 2; 15% probability 3, and 2% probability 4. (we may later on need to adjust these probabilities) Create the relevant number of instances, randomly populating the attributeStrings based on the UmpleClass, and adding the new instance to partiallyCreatedObjectsQueue and to instanceMap, then process the object according to step D below
D. To add associations for a new object in partiallyCreatedObjectsQueue For each association in the UmpleClass of the object If there as already an UmpleLink for the UmpleAssociation for this object, then stop unless there are less than n, see the 4th case below (this can happen if the link is created from the other end) Do the following, depending on the association pattern; -- 0..1 Randomly create a link with probability 50% picking some other instance of the class at the other end that doesn't yet have (enough) back-links of this association to satisfy its multiplicity, and doesn't yet exceed it. If no class at the other end of the association has an instance yet, or they all already have enough back links, then you will need to first create one as in step C -- * Same, but 33% chance of 0; 33% chance of 1; 30% chance of 2 and 3% chance of 3 -- 1 Same, but definitely create a link (to an existing or new object) -- n (where n is greater than 1) Same, but add enough links so there are now n links After dealing with all associations, remove from partiallyCreatedObjectsQueue
Keep repeating step D until partiallyCreatedObjectsQueue is empty.
Go back to step B and see if there are any more classes with no instances, to keep going with the process.
E. When all the above is done, we can generate the diagram just like we would generate a class diagram, except that instead of processing classes and associations we are processing our instances and links.