Following question also refers to discussion in following questions as well
https://stackoverflow.com/search?page=2&tab=Relevance&q=one%20to%20many%20unidirectional%20java
Best practise for adding a bidirectional relation in OO model
I tried to implementing 8 association combinations formed by [Unidirectional/Bidirectional] X [(One/Many) to (One/Many)] in Java. I found two cases can not be implemented namely Unidirectional One to One and Unidirectional One to Many (e.g. Person->*Vehicle). Other 6 combinations and Composition are possible programatically.
I Feel its not only the case with Java, these 2 cases do not exist. e.g. Use case - allocate one Aadhar/SSN number to only one person is possible if we know that number is not allocated to anybody else (reverse navigation is must). Does this mean we need to take care while making our design model not to arrive at these specific associations (though they might be present in analysis model)? I am confused on this.
Basic (No Aggregation)
If you are looking at basic unidirectional association, then that's the simplest of them all.
Unidirectional One to One
class Person {
String name;
}
Unidirectional One to Many
class Person {
List vehicles;
}
Composite Aggregation
If I assume that you are asking about composite relationshions (where one SSN can be assigned to at most one person), then you can still implement it.
How exactly you decide to implement it is however subject to your specific domain or e.g. how you store your data, because
reverse navigation is must
is not actually true, because you can just check all Person instances; or you can store all the SSNs in a smart data structure that allows you to quickly check if a new one is unique, and then you would assign it to the Person without additional checks, because you already know that it is unique).
Or you can implement also the opposite lookup, which is not prohibited even if the association is "uni-directional"
To quote the UML Specs (11.5.3.1 Associations) [emphasis mine]:
Navigability means that instances participating in links at runtime (instances of an Association) can be
accessed efficiently from instances at the other ends of the Association. The precise mechanism by which such efficient
access is achieved is implementation specific. If an end is not navigable, access from the other ends may or may not be
possible, and if it is, it might not be efficient.
Update from comments
Noone claims that upholding the relationship constraints has to be done in the accessors. In fact pretty much always you will have temporarily invalid relationships, imagine:
person = new Person();
// right now person is invalid state because it doesn't have an SSN
ssn = ssnGenerator.createNew();
// now ssn is also in invalid state because it has no person
person.setSSN(ssn);
// only now is person and ssn valid
(creating a constructor wouldn't help, because constructor is called after the object has already been created (so another part of the constructor could need the ssn already set).
So it is the responsibility of the programmer to ensure that the system upholds all constraints in whatever way it makes most sense. Using constructors/accessors is the easiest way in some circumstances, but you could e.g. wrap the code above in an atomic transaction. After all, if you kept your validation in the setSSN(), then what would happen if the programmer were to forget to call the method at all?
(person 1->* vehicle)
p1.add(v1) and p2.add(v1) are possible violations
You asked about "person ->* vehicle", now you've changed it to "person 1 -> * vehicle" so obviously the answer differs. But the same principle as above applies -- it is the responsibility of the system to uphold all constraints, and wherever that's done in accessors, validation methods, or the way the system constructed is an implementational detail -- there's no single best way, and there will be always trade-offs.