I want to implement a model checker for Java class diagrams.
There are many constraints that I've been considered for a while.
Hope anyone can help me figure it out.
All the cycles here I mean are pure cycles with only one type of relationship.
Q1: Suppose class A is composed of class B, is it possible that class B is also composed of class A, given that class A and class B are different classes? Moreover, is it possible for composition relationship to have cycles?
Q2: What about other relationship in the class diagram, like aggregation, dependence and association? What's the meaning of cycles in these relationships? Can anyone give some examples?
Thanks for reading my question and hope someone can help me out.
Q1: Suppose class A is composed of class B, is it possible that class B is also composed of class A, given that class A and class B are different classes? Moreover, is it possible for composition relationship to have cycles?
Strictly speaking in UML terms... yes, but you'd be hard pressed to actually implement this in code. If you ask yourself, "can B stand alone without A?" and "can A stand alone without B?" If you can answer no to both of those at the same time, then you can have two classes composed of each other. Since one would have to be able to stand on its own for the other to be composed of it, you can't have both. However, since composition vs aggregation is largely based on design and context, it's not completely impossible. You can for instance, have something like this:
Class B
contains a reference to A
, and A
contains a reference to B
public class A {
B myB;
String name = "A";
public A(int num) {
this.name += num;
}
public void setMyB(B b) {
this.myB = b;
}
public B getMyB() {
return this.myB;
}
public String getName() {
return this.name;
}
}
public class B {
A myA;
String name = "B";
public B(int num) {
this.name += num;
myA = new A(num);
}
public A getMyA() {
return this.myA;
}
public String getName() {
return this.name;
}
}
In this example, we provide an identifier for the class using a defined String
and then append a number to it, just to show some unique ID.
We provide methods that allow us to access both A
and B
references, but only B
creates its reference to the other via the constructor (composition).
Using this simple test:
public class Test {
public static void main(String[] args) {
A myA = new A(1);
B myB = new B(2);
B anotherB = new B(3);
myA.setMyB(anotherB);
System.out.println("A = " + myA.getName());
System.out.println("A's B = " + myA.getMyB().getName());
System.out.println("B = " + myB.getName());
System.out.println("B'a A = " + myB.getMyA().getName());
}
}
We can see the following output
A = A1
A's B = B3
B = B2
B'a A = A2
In this example, the B reference in A
is created outside the context of A
and passed in as an argument. If we deleted myB
, we'd lose the reference to its A
, but not if we deleted myA
(we still have anotherB
.
Suppose we eliminated the setMyB()
method from A
and moved it to the constructor... we'd have an infinite loop of new objects and you'd end up with a StackOverflowError
You could probably get creative and try to implement the Singleton pattern or some other construct that limits the number of objects created, but doing so would mean the constructors would need to be private/hidden, which prevents extension by other classes. Use of a static field to track number of creations might prevent the error, but then you'd lose all the references without having a place to keep track of them all, and lastly, you'd never have a "perfect" composition, because one class would be missing its component.
After all this "analysis" you'd end up coming up with a design that makes sense, not one that strictly fits what's drawn on a UML diagram. The UML diagram is there to convey "relationships" between classes. The "unique" case you've asked about here where A uses B and B uses A is probably not going to be solved with UML modeling, but probably needs some other design work.
Q2: What about other relationship in the class diagram, like aggregation, dependence and association? What's the meaning of cycles in these relationships? Can anyone give some examples?
Association relationships are really used to describe the type of relationships that are defined by composition, aggregation, many-to-many, one-to-one etc, and depend on the context. The meaning of cycles in every association is going to depend on your design.
In general, a cycle in a dependency means that the class depends on itself. This could be for recursive function calling, Singleton design pattern implementation, or some other design pattern requiring a class to refer to itself.
Aggregation was sort of already answered above. It basically means the object "uses" whatever it's aggregating. An example is a Company
aggregates People
. When the company goes away, the people still exist. A cycle in that kind of relationship is similar to what was shown in my example, except you'd have external references to both A
and B
classes that were passed as arguments to the first two references to A
and B
.
The bottom line is... UML is a tool to show relationships between classes. The design and implementation will follow from that and the fact that you have "interesting" relationships modeled with UML will not help you get past serious design roadblocks.
Hopefully this helps shed some light on your questions.