Re: Implementation of [A]1---->*[B]

From: H. S. Lahman (h.lahman_at_verizon.net)
Date: 08/16/04


Date: Mon, 16 Aug 2004 21:58:48 GMT

Responding to Loeffelholz...

> concerning following kind of association:
>
> [A]1----->*[B]
>
> Concrete, for instance:
>
> [Company]1---->*[Employee]*<----1[Project]
>
> How can one prevent that an Employee is referenced more than one time by a
> Project?

OOA/D relationships are about constraints on how set members of two
different sets can participate in a relationship. Since OOA/D class
membership is based upon identity, one can't have duplicate set members.
  Therefore the '*' relationships cannot have duplicates.

So I assume your question is: how does one avoid duplicate references
when /instantiating/ a '*' relationship? The short answer is that is up
to whoever instantiates the relationship to enforce the rules.

That's trivial when the same object instantiates the relationship and
the object itself. It gets nastier when the participants in a
collaboration are swapped or participation is temporally conditional.
In that case whoever is instantiating the relationship may have to check
if the instance is already a participant.

One can do that with the collection's add() function if the appropriate
reaction to it already being there is to do nothing. After all, it is
already there, which is what the caller wanted.

OTOH, if it is considered an error to /try/ to add a participant that is
already there, I would <usually> opt for the caller invoking a find()
first to determine if it was there. That's because treating it as an
error means that the requirements specifically recognize the attempt to
add as something special that has its own unique business rules and
policies. IMO, that warrants encapsulation somewhere beyond the ken of
a collection class that has rather mundane and dreary responsibilities
for managing a set.

For example, checking user input requires special processing if the user
screws up. That processing will be defined in the requirements. So I
would expect the checking to be done where that special processing is
triggered rather than being separated from it by placing it in the
collection class who checks for the problem but doesn't act on it. IOW,
I see the rules and policies for dealing with the special situation as
logically cohesive with the check for the special situation.

[Having find() return NOT FOUND is not the same as checking if a member
being added is already there, The NOT FOUND return is a normal return
for any context where one attempts to extract a member and it isn't
there because there is no context where one wouldn't care. Having add()
return ALREADY THERE is only relevant to the context where one cares
about whether it is already there. In addition, it reduces the cohesion
of the add() responsibility because it is adding an additional
responsibility to tell the caller if it was already there.]

>
> My thoughts so far are:
>
> 1. A Project holds its own copy of Employee. Dropped out, because Employee
> is a reference object and there are other references to it.

That gets real messy if '*' is large or the number of relevant Employees
changes dynamically or from one project to the next. That's why the
Computer Scientist in the Sky invented collection classes.

>
> 2. Prevent it over the GUI. Okay, but it wouldn't prevent that I - as the
> programmer - do this mistake accidently somewhere in the code.

I'm not sure what this means. There is either a DB somewhere with the
relationship or there are a bunch of objects in memory with the
relationship. Either way the relationship collection has to be queried
by somebody.

If it exists in the GUI (e.g., the contents of a pick list box), then
check it there. Otherwise ask the application solution if it is already
there. If the application solution doesn't have the objects related in
memory, it can relay the request to the DB.

>
> 3. Create a ProjectManager class which would check all Projects if one would
> add a Employee to a Project. Okay, but seems to me as a too great efford
> for all such kind of associations.

This sounds like a different problem where you are trying to prevent the
same Employee from working on two projects. That is already precluded
in the '1' multiplicity on the [Project] side.

As a practical matter, that is usually trivial to enforce because one
will have a single referential attribute embedded in Employee. It will
only be an issue if the relationship is conditional or participants are
swapped. (Otherwise it would be set once when the Employee instance was
created and there would be no setter.)

The same basic idea applies as for add() in the '*' collection case
above. It is the responsibility of whoever instantiates the
relationship to enforce the rules. If the idea is for the "current"
participant, then the setter simply replaces whatever was there.
Otherwise, if one cares about trying to assign a project when the
Employee is already assigned to one, the instantiator should check first
(i.e., invoke the Project getter on Employee and check for a NOT FOUND
return) and then take the appropriate action.

*************
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl@pathfindermda.com
Pathfinder Solutions -- Put MDA to Work
http://www.pathfindermda.com
blog (under constr): http://pathfinderpeople.blogs.com/hslahman
(888)-OOA-PATH



Relevant Pages

  • Re: OT ~ Happy Days Are Here Again
    ... Every single one of those references go back to the first article in ... White House employee in the meeting told them the President of the ... Not one single source that was actually in the meeting. ... no other source has any references or a name of anyone who was ...
    (rec.outdoors.rv-travel)
  • Re: Leech (?) content of mySQL tables
    ... the foregin key AND referential integrity are not supported in all type ... Create table employee (" ... references employee on delete cascade on update cascade") ## ...
    (comp.lang.php)
  • Re: OT: Job References; are they any real value?
    ... I haven't been an employee (except as a legal fiction for a temp agency, ... I don't like my references to be bothered with a ... give names and numbers of folks I've worked with. ... great programmer... ...
    (comp.lang.cobol)
  • Re: Which database design is better
    ... you can update primary keys because you can ... of employee. ... Remember that part in the specs in this thread about each store ... then I can use a REFERENCES clause. ...
    (microsoft.public.sqlserver.programming)
  • Re: Looking for PCB layout designer
    ... > objecting to your stating that 10+ layer boards and BGAs weren't all that ... Descrimination against smart people is ... questionaires/quizzes available to any prospective employee. ... The primary responsibility was to pick up trash and mow ...
    (sci.electronics.design)