After reading the question "In UML class diagram can composition be bidirectional?", I'm wondering how concrete examples of bi-directional shared/composite aggregation will look on a UML diagram. Specifically, I'm interested how arrow-heads and multiplicity are used to distinguish between the following cases:
1) Uni-directional shared aggregation (aggregation)
class Foo {
// Can contain 0+ elements
ArrayList<Bar> bars = new ArrayList<>();
void addBar(Bar bar) {
bars.add(bar);
}
}
class Bar {...}
2) Bi-directional shared aggregation (aggregation)
class Foo {
// Can contain 0+ elements
ArrayList<Bar> bars = new ArrayList<>();
void addBar(Bar bar) {
bars.add(bar);
bar.setFoo(this);
}
}
class Bar {
Foo foo;
void setFoo(Foo foo) {
this.foo = foo;
}
}
3) Uni-directional composite aggregation (composition)
class Foo {
// Can contain 0+ elements
ArrayList<Bar> bars = new ArrayList<>();
void addBar() {
bars.add(new Bar());
}
}
class Bar {...}
4) Bi-directional composite aggregation (composition)
class Foo {
// Can contain 0+ elements
ArrayList<Bar> bars = new ArrayList<>();
void addBar() {
bars.add(new Bar(this));
}
}
class Bar {
Bar foo;
Bar(Foo foo) {
this.foo = foo;
}
}
Case 1 and 2 should be straightforward. I'm not sure how to represent the bi-directional associations, and how to distinguish them from the uni-directional ones, as both will have multiplicities on both sides. The diagram must include multiplicities.