Discussion:
Many to many relaties in OO, vergeleken met die uit ERD's
(te oud om op te antwoorden)
Paul
2003-12-30 13:45:25 UTC
Permalink
Als iemand met een professionele achtergrond in datamodellering die nu
een overgang maakt naar OO valt me het onderstaande op:

Het lijkt me dat concepten als entiteit en object gerelateerd aan
elkaar zijn. Toch bestaan binnen een ERD veel many-to-many relaties
die opgelost worden middels een koppeltabel. Vaak zijn koppeltabellen
betekenisloos: zuivere constructies. Iets dergelijks vind ik (bijna)
niet terug in conceptuele modellen/class diagrammen. Daar lijken (?)
er veelal bestaande zaken gemodelleerd te worden.

Ik weet dat binnen OO verschillende mogelijkheden bestaan om M:N
relatie op te lossen:

1. Associatieklasse
2. Uitwerking middels "koppelklasse"; vergelijkbaar met een
koppelentiteit.
3. Toepassen van dimensiereductie; formeel is de relatie M:N, maar men
beperkt de zichtbaarheid tot 1:N.

Alle voorbeelden waar ik de hand op weet te leggen zijn echter niet
duidelijk in het M:N stuk.

Wie kan meer duidelijkheid geven in de relatie ERD en OO?
Rene Pijlman
2003-12-30 14:00:16 UTC
Permalink
Post by Paul
Het lijkt me dat concepten als entiteit en object gerelateerd aan
elkaar zijn. Toch bestaan binnen een ERD veel many-to-many relaties
die opgelost worden middels een koppeltabel.
Eh nee, in ERD bestaan geen koppeltabellen. Die ontstaan pas als je gaat
afbeelden op een relationeel databasemodel.
Post by Paul
Wie kan meer duidelijkheid geven in de relatie ERD en OO?
ERD/OO lijkt me vrij duidelijk, met dien verstande dat ERD over het
datamodel gaat en OO over objecten (= groepering van data en methoden).
Maar het datadeel is min of meer 1-op-1 op elkaar af te beelden.

De uitdaging is het afbeelden van een ERD- of OO-model op een relationele
database (als je geen OO-database wilt gebruiken). Daar zijn verschillende
modellen voor. Er is eindeloos veel over te vinden op het web:
http://www.google.nl/search?q=oo+relational+mapping
--
René Pijlman

Wat wil jij leren? http://www.leren.nl
Paul
2003-12-30 14:14:38 UTC
Permalink
Rene,
Post by Rene Pijlman
Post by Paul
Het lijkt me dat concepten als entiteit en object gerelateerd aan
elkaar zijn. Toch bestaan binnen een ERD veel many-to-many relaties
die opgelost worden middels een koppeltabel.
Eh nee, in ERD bestaan geen koppeltabellen. Die ontstaan pas als je gaat
afbeelden op een relationeel databasemodel.
Het punt waarmee ik zit is het volgende:

Stel een klant heeft meerdere materiaaltype in opslag gegeven bij een derde
partij. Een materiaaltype kan ook door een andere klant in opslag gegeven
zijn. Dus klant en materiaaltype hebben een M:N relatie met elkaar. Nu heeft
wordt er bij een bepaalde klant-materiaal combinatie een serie diensten
verleend. Een dienst kan verleend worden bij meerdere klant-materiaal
combinaties. Ook weer een M:N relatie. In een datamodel (ik wil geen
argument starten over logisch of fysische datamodellen), is dit eenvoudig te
modelleren middels koppelentiteiten. De koppelentiteit tussen klant en
materiaal is zuiver (geen extra attributen). Hoe doe je hetzelfde in OO?

Het afbeelden van een OO model op een RDBMS is een heel andere kwestie. Daar
ben ik nog niet mee bezig :-).

Gr. Paul.
Rene Pijlman
2003-12-30 14:34:31 UTC
Permalink
In een datamodel, is dit eenvoudig te modelleren middels koppelentiteiten.
De koppelentiteit tussen klant en materiaal is zuiver (geen extra attributen).
Hoe doe je hetzelfde in OO?
Ik weet niet zeker of ik het verhaal goed begrijp, maar vermoedelijk met
een association class. Zie o.a.
http://etna.int-evry.fr/COURS/UML/notation/notation5d.html
--
René Pijlman

Wat wil jij leren? http://www.leren.nl
Sjoerd A. Schreuder
2003-12-30 14:44:31 UTC
Permalink
Post by Paul
Als iemand met een professionele achtergrond in datamodellering die nu
Het lijkt me dat concepten als entiteit en object gerelateerd aan
elkaar zijn. Toch bestaan binnen een ERD veel many-to-many relaties
die opgelost worden middels een koppeltabel. Vaak zijn koppeltabellen
betekenisloos: zuivere constructies. Iets dergelijks vind ik (bijna)
niet terug in conceptuele modellen/class diagrammen. Daar lijken (?)
er veelal bestaande zaken gemodelleerd te worden.
Ik weet dat binnen OO verschillende mogelijkheden bestaan om M:N
1. Associatieklasse
2. Uitwerking middels "koppelklasse"; vergelijkbaar met een
koppelentiteit.
Die twee oplossingen zie ik eigenlijk nooit toegepast worden in OO.
Ze komen een beetje te veel ERD-achtig op me over.

Waar ERD informatie centraal in een tabel opslaat, slaat OO vaak
de informatie verspreid over de objecten op. Dat is een heel
andere aanpak, waardoor de oplossingen ook zeer verschillend zullen
zijn.

Als je OO wilt leren denken, zul je een aantal ERD reflexen moeten
afleren.
Post by Paul
3. Toepassen van dimensiereductie; formeel is de relatie M:N, maar men
beperkt de zichtbaarheid tot 1:N.
Tja, dat kan natuurlijk altijd. Maar de OO oplossing voor M:N heeft
zoveel voordelen, dat zelfs de 1:N op die manier worden aangepakt.
Dus dit lost eigenlijk ook niets op.
Post by Paul
Alle voorbeelden waar ik de hand op weet te leggen zijn echter niet
duidelijk in het M:N stuk.
Wie kan meer duidelijkheid geven in de relatie ERD en OO?
Laten we een stapje terug doen. Bij een M:N relatie heb je twee
kanten op een 1:N relatie die consistent met elkaar moeten zijn.
Want als A een relatie heeft met B, moet B dus ook de inverse relatie
met A hebben.

Bij tabellen is het niet mogelijk om een onbekend aantal waarden in
een row op te nemen. Bij objecten is het wel goed mogelijk om een
container (dynamische array of lijst of iets dergelijks) in het
object op te nemen.

Bij ERD moet je de informatie dus sowieso al in een aparte tabel zetten.
Bij M:N zouden dat twee tabellen worden, maar die zouden toch indentiek
worden, dus wordt het een tabel met twee indices. Dit heeft als voordeel
dat de informatie maar op een enkele plaats staat, en er dus geen
consistentie problemen kunnen ontstaan.

Bij OO kun je de informatie wel binnen het object zelf opslaan.
Wel moet je opletten op de consistentie. Gelukkig is het bij OO
zeer gebruikelijk om stukken code te laten uitvoeren als je
data update. Dus bij OO wordt meestal gekozen om de updates
via een aparte procedure te laten verlopen die beide relaties
tegelijk aanpast, zodat consistentie gegarandeerd is.

Het voordeel van die aanpak is dat je niet in een aparte structuur
hoeft op te zoeken welke objecten gerelateerd zijn, maar dat je
gewoon referenties in een containers in het object zelf opslaat.

Een nadeel is dat als door een bug de consistentie fout loopt,
je dat pas op een heel andere plek zult merken en het debuggen
dus vervelend zal worden. Unit-tests, om de relatie-beheer-code
apart te testen, kunnen hierbij helpen.

Een simpel voorbeeld (pseudo-code). Je hebt een klasse Vriend
met daarin een container Vrienden met nul of meer referenties
naar een Vriend. Deze container is 'private', dus alleen
toegankelijk voor procedures van de klasse Vriend.

procedure Vriend.NieuweVriendschap(Vriend B);
begin
self.Vrienden.Add(B);
B.Vrienden.Add(self);
end;

procedure Vriend.VerwijderVriendschap(Vriend B);
begin
self.Vrienden.Remove(B);
B.Vrienden.Remove(self);
end;

destructor Vriend.Destroy;
begin
for i in self.Vrienden do
begin
i.Vrienden.Remove(self);
end;
self.Vrienden.Clear; // Voor het geval dat...
end;

Zolang je verder nooit de container Vrienden aanpast, blijven
de relaties consistent. Je kunt natuurlijk wel de inhoud bekijken,
zoals met:

function Vriend.IsBevriendMet(Vriend B);
begin
return self.Vrienden.IsPresent(B);
end;

Op deze manier heb je altijd de relaties binnen handbereik, zonder
moeilijk te moeten doen ze in een andere tabel of structuur op te
zoeken. Dat komt de snelheid ten goede. Het gaat wel ten koste
van een beetje geheugen, maar wie maalt daar tegenwoordig nog om?

Deze aanpak heeft zo veel voordelen en zo weinig nadelen, dat
zelfs 1:N relaties vaak op deze manier worden aangepakt.
Voorbeeld: een werknemer heeft een enkele referentie naar zijn baas,
maar elke baas heeft een hele container met referenties naar
zijn ondergeschikten. In ERD moet je die inverse relatie
(baas->werknemer) steeds opnieuw weer opbouwen.

Hopelijk verduidelijkt dit een beetje hoe je met OO dit probleem
oplost. De oplossing is dus duidelijk anders dan bij ERD.

Als je een echt en complex voorbeeld wilt bekijken, kijk dan
naar Observer/Observable die vrij centraal staat binnen de
event-driven aanpak die vaak met OO gepaard gaat. Maar dat
zou voor een beginner misschien nog iets te complex kunnen
zijn.

Sjoerd Schreuder
Paul
2003-12-30 15:17:16 UTC
Permalink
"Sjoerd A. Schreuder" <***@wanadoo.nl> schreef in bericht news:3ff18f4f$0$149$***@news.wanadoo.nl...


OK. Ik zie waar je heen gaat. Beide entiteiten houden een interne lijst
(Vector?) bij van de relatie. Dit lost inderdaad uitstekend n:m relaties op.
Maar nu een complicerende factor: wat nu als de relatie zelf betekenis
heeft? Doordat er een relatie bestaat tussen A en B kan aanvullend gedrag
beschreven worden op de combinatie. Voorbeeld:

Klant 0..* <---> 0..* Materiaaltype

Op de combinatie tussen een klant en een materiaaltype kunnen bijvoorbeeld
instanties van een nieuwe klasse toegevoegd worden. Bijvoorbeeld de klasse
"diensten". Ook weer N:M bijvoorbeeld:

KlantMateriaalType 0..* <---> 0..* Dienst

Hoe ga je daarmee om?

Groeten,

Paul.
Sjoerd A. Schreuder
2003-12-30 16:37:14 UTC
Permalink
Post by Paul
OK. Ik zie waar je heen gaat. Beide entiteiten houden een interne lijst
(Vector?) bij van de relatie. Dit lost inderdaad uitstekend n:m relaties op.
Maar nu een complicerende factor: wat nu als de relatie zelf betekenis
heeft? Doordat er een relatie bestaat tussen A en B kan aanvullend gedrag
Klant 0..* <---> 0..* Materiaaltype
De term "aanvullend gedrag" doet in OO al snel het belletje "nieuwe klasse"
rinkelen.
Post by Paul
Op de combinatie tussen een klant en een materiaaltype kunnen bijvoorbeeld
instanties van een nieuwe klasse toegevoegd worden. Bijvoorbeeld de klasse
KlantMateriaalType 0..* <---> 0..* Dienst
Hoe ga je daarmee om?
Dan moet je er inderdaad wel een aparte klasse van maken. Dat voelt
voor mij ook zeer intuitief aan, omdat je naar de relatie zelf wilt
verwijzen. De relatie is daardoor een entiteit geworden.

Voor simpele M:N relaties lijkt me dat echter overkill. Het doel
van OO is niet om zo veel mogelijk klassen aan te maken, ook al
lijkt dat soms wel zo. :-)

Terzijde: Ik zou de naam KlantMateriaalType nooit gebruiken, maar iets
als DienstOnderdeel gebruiken. Natuurlijk zit daar (een referentie naar)
een Klant en een Materiaal in, maar ik hou de naam liever abstracter.
Reden: als er later b.v. een Magazijn in een DienstOnderdeel moet
worden opgenomen, hoef je de naam niet aan te passen. KlantMateriaalType
zou je dan tot KlantMateriaalMagazijnType moeten omschrijven; of
je moet accepteren dat de naam verwarrend is geworden.

Sjoerd Schreuder
Paul
2003-12-30 20:18:01 UTC
Permalink
Post by Sjoerd A. Schreuder
Post by Paul
OK. Ik zie waar je heen gaat. Beide entiteiten houden een interne lijst
(Vector?) bij van de relatie. Dit lost inderdaad uitstekend n:m relaties op.
Maar nu een complicerende factor: wat nu als de relatie zelf betekenis
heeft? Doordat er een relatie bestaat tussen A en B kan aanvullend gedrag
Klant 0..* <---> 0..* Materiaaltype
De term "aanvullend gedrag" doet in OO al snel het belletje "nieuwe klasse"
rinkelen.
Post by Paul
Op de combinatie tussen een klant en een materiaaltype kunnen bijvoorbeeld
instanties van een nieuwe klasse toegevoegd worden. Bijvoorbeeld de klasse
KlantMateriaalType 0..* <---> 0..* Dienst
Hoe ga je daarmee om?
Dan moet je er inderdaad wel een aparte klasse van maken. Dat voelt
voor mij ook zeer intuitief aan, omdat je naar de relatie zelf wilt
verwijzen. De relatie is daardoor een entiteit geworden.
OK, lijkt me ook logisch. Vond het vreemd dat ik dit niet vaker terug zag in
conceptuele/design modellen.
Post by Sjoerd A. Schreuder
Voor simpele M:N relaties lijkt me dat echter overkill. Het doel
van OO is niet om zo veel mogelijk klassen aan te maken, ook al
lijkt dat soms wel zo. :-)
:-)
Post by Sjoerd A. Schreuder
Terzijde: Ik zou de naam KlantMateriaalType nooit gebruiken, maar iets
als DienstOnderdeel gebruiken. Natuurlijk zit daar (een referentie naar)
een Klant en een Materiaal in, maar ik hou de naam liever abstracter.
Reden: als er later b.v. een Magazijn in een DienstOnderdeel moet
worden opgenomen, hoef je de naam niet aan te passen. KlantMateriaalType
zou je dan tot KlantMateriaalMagazijnType moeten omschrijven; of
je moet accepteren dat de naam verwarrend is geworden.
Sjoerd Schreuder
Daar zit waarschijnlijk de crux: naamgeving. Vooral in het OO-stuk zal ik
daar wat meer aandacht aangeven.
Bedankt voor je bevestiging en tips!

Paul.
Suzan Foster
2003-12-30 18:06:27 UTC
Permalink
Post by Sjoerd A. Schreuder
Een simpel voorbeeld (pseudo-code). Je hebt een klasse Vriend
met daarin een container Vrienden met nul of meer referenties
naar een Vriend. Deze container is 'private', dus alleen
toegankelijk voor procedures van de klasse Vriend.
procedure Vriend.NieuweVriendschap(Vriend B);
begin
self.Vrienden.Add(B);
B.Vrienden.Add(self);
end;
dit kan niet met private, bedoel je niet protected?

groetjes, su.
Sjoerd A. Schreuder
2003-12-30 19:02:38 UTC
Permalink
Post by Suzan Foster
Post by Sjoerd A. Schreuder
Een simpel voorbeeld (pseudo-code). Je hebt een klasse Vriend
met daarin een container Vrienden met nul of meer referenties
naar een Vriend. Deze container is 'private', dus alleen
toegankelijk voor procedures van de klasse Vriend.
procedure Vriend.NieuweVriendschap(Vriend B);
begin
self.Vrienden.Add(B);
B.Vrienden.Add(self);
end;
dit kan niet met private, bedoel je niet protected?
Hangt dat niet van de taal af? De betekenis van 'private'
en 'protected' verschilt al tussen C++ en Java, dus dat
zal tussen andere talen nog wel anders zijn.

Nou heb ik al een paar maanden niet in C++ gecodeerd, dus het kan
zijn dat ik er een beetje uit begin te raken. Maar ik dacht dat
het daar wel met 'private' kan. 'protected' in C++ gebruik ik
alleen als afgeleide klassen er bij moeten, en dat wil ik hier juist
niet. Dan gebruik ik nog liever "friend class Vriend;", maar dat
is juist iets dat in C++ impliciet altijd al geldt. Dus ik verwacht
dat het in C++ wel met 'private' kan werken. Maar als ik dan Delphi-
achtige syntax gebruik en het kan in Delphi juist niet met 'private',
dan verwar ik de boel alleen maar.

Anyway, ik bedoel natuurlijk "niet public" of "zo beperkt mogelijk",
zodat je controle hebt over wie wel toegang heeft. Het hangt toch
sterk van de taal af welk keyword je daarvoor moet gebruiken.

Sjoerd
Frans Bouma
2003-12-30 17:21:23 UTC
Permalink
Post by Paul
Als iemand met een professionele achtergrond in datamodellering die nu
Het lijkt me dat concepten als entiteit en object gerelateerd aan
elkaar zijn. Toch bestaan binnen een ERD veel many-to-many relaties
die opgelost worden middels een koppeltabel. Vaak zijn koppeltabellen
betekenisloos: zuivere constructies. Iets dergelijks vind ik (bijna)
niet terug in conceptuele modellen/class diagrammen. Daar lijken (?)
er veelal bestaande zaken gemodelleerd te worden.
Ik weet dat binnen OO verschillende mogelijkheden bestaan om M:N
1. Associatieklasse
2. Uitwerking middels "koppelklasse"; vergelijkbaar met een
koppelentiteit.
3. Toepassen van dimensiereductie; formeel is de relatie M:N, maar men
beperkt de zichtbaarheid tot 1:N.
Alle voorbeelden waar ik de hand op weet te leggen zijn echter niet
duidelijk in het M:N stuk.
Wie kan meer duidelijkheid geven in de relatie ERD en OO?
Een m:n relatie is altijd redundant, want in theorie is de
koppeltabel ook een entity, immers een entity == relation == verzameling
attributes. Een m:n relation valt dus altijd uiteen in een 1:n en m:1
relatie, die lopen via een intermediate table/entity.

Het is interessanter om te kijken naar m:n relations die verlopen
via een intermediate table waar non-PK fields in zitten. Bv Order-Product
via OrderDetailRow. OrderDetailRow heeft meer informatie, maar is ook de
intermediate table tussen Order en Product.

Het is daarom inconsistent om te zeggen dat je 'dan maar wel' een
aparte entity herkent maar 'anders niet'. Want wat te doen wanneer je een
m:n relation 'objectified': Department - Employee hebben een m:n relatie,
fysiek gerealiseerd in de table DepartmentEmployee. Dit lijkt een
'betekenisloze' intermediate table, echter wanneer de m:n relation wordt
geobjectified omdat je 'StartDate' wilt vastleggen, te weten de datum
wanneer een employee is begonnen met werken voor een department, de
intermediate table 1 column erbij krijgt (non-PK) maar dat deze eens lege
intermediate table ineens een volwaardige entiteit is (voor de mensen die
de 'betekenisloze' intermediate table niet voor vol aanzagen).

Als je consistent je code opbouwt zodat je altijd intermediate
tables ziet aparte entities (redenerend vanuit het relationele model naar
OO toe) heb je geen problemen in OO, immers voor je code is het onmogelijk
onderscheid te maken tussen:

Employee.Departments
en
Employee.Departments

de ene is een m:n relation lopende via een andere entity
(DepartmentEmployee, met de StartDate) en de andere niet. Om nu deze
relatie vast te leggen in de DB vanuit je code (een employee start bij een
nieuw department) moet je soms wel (de ene) en soms niet (de andere) een
apart entity vullen (de startdate moet een value hebben). Dit is
inconsistent en kan gevolgen hebben voor je code wanneer je ineens die
column gaat toevoegen in de DB.

FB
--
Get LLBLGen Pro, the new O/R mapper for .NET: http://www.llblgen.com
Servé Lau
2003-12-30 17:47:02 UTC
Permalink
"Frans Bouma" <***@xs4all.nl> wrote in message

he, kijk eens wie terug is :-)
Frans Bouma
2003-12-30 18:14:37 UTC
Permalink
Post by Servé Lau
he, kijk eens wie terug is :-)
Heh :) Ja ik was toevallig aan het browsen naar materiaal voor mn
multiple-inheritance in .NET plea en kwam een discussie tegen daarover in
nl.comp.programmeren, dus ik dacht heee, hoe zou het daar zijn? Wel wat
stiller dan vroeger moet ik toegeven maar toch maar weer even gesubscribed
:)
FB
--
Get LLBLGen Pro, the new O/R mapper for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Servé Lau
2003-12-30 18:51:12 UTC
Permalink
Post by Frans Bouma
Heh :) Ja ik was toevallig aan het browsen naar materiaal voor mn
multiple-inheritance in .NET plea en kwam een discussie tegen daarover in
nl.comp.programmeren, dus ik dacht heee, hoe zou het daar zijn? Wel wat
stiller dan vroeger moet ik toegeven maar toch maar weer even gesubscribed
goed hoor.
Zit MI eraan te komen dan in .NET?
Frans Bouma
2003-12-30 19:11:01 UTC
Permalink
Post by Servé Lau
Post by Frans Bouma
Heh :) Ja ik was toevallig aan het browsen naar materiaal voor mn
multiple-inheritance in .NET plea en kwam een discussie tegen daarover in
nl.comp.programmeren, dus ik dacht heee, hoe zou het daar zijn? Wel wat
stiller dan vroeger moet ik toegeven maar toch maar weer even
gesubscribed
Post by Servé Lau
goed hoor.
Zit MI eraan te komen dan in .NET?
Nee juist niet, maar het is wel nodig, omdat .NET interfaces
implementeert die je niet zelf na kunt bouwen (ServicedComponent bv) en je
dus in de knoop zit (je kunt de MI designs niet omcatten naar SI designs :))

FB
--
Get LLBLGen Pro, the new O/R mapper for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Paul
2003-12-30 20:30:06 UTC
Permalink
[...knip]
Post by Frans Bouma
Een m:n relatie is altijd redundant, want in theorie is de
koppeltabel ook een entity, immers een entity == relation == verzameling
attributes. Een m:n relation valt dus altijd uiteen in een 1:n en m:1
relatie, die lopen via een intermediate table/entity.
Het is interessanter om te kijken naar m:n relations die verlopen
via een intermediate table waar non-PK fields in zitten. Bv Order-Product
via OrderDetailRow. OrderDetailRow heeft meer informatie, maar is ook de
intermediate table tussen Order en Product.
Het is daarom inconsistent om te zeggen dat je 'dan maar wel' een
aparte entity herkent maar 'anders niet'. Want wat te doen wanneer je een
m:n relation 'objectified': Department - Employee hebben een m:n relatie,
fysiek gerealiseerd in de table DepartmentEmployee. Dit lijkt een
'betekenisloze' intermediate table, echter wanneer de m:n relation wordt
geobjectified omdat je 'StartDate' wilt vastleggen, te weten de datum
wanneer een employee is begonnen met werken voor een department, de
intermediate table 1 column erbij krijgt (non-PK) maar dat deze eens lege
intermediate table ineens een volwaardige entiteit is (voor de mensen die
de 'betekenisloze' intermediate table niet voor vol aanzagen).
Voor de record: een zuivere koppelentiteit is absoluut een volwaardige
entiteit, maar heeft geen aanvullende attributen behalve die van z'n ouders.
Vandaar de term "zuiver" [Finkelstein of Reingruber als ik me niet vergis].
Een "onzuivere" koppelentiteit heeft extra attributen. In het eerste geval
_zou_ je ervoor kunnen kiezen om de n:m relatie te implementeren middels
lists binnen de klassen. Voor onzuivere koppelentiteiten ligt een aparte
klasse voor de hand.

Het wordt interessanter wanneer je een zuivere koppelentiteit hebt, waarbij
de relatie tussen entiteit A en B betekenis heeft voor entiteit C. Het lijkt
me, en andere posters over deze kwestie, dat je dan toch een nieuwe klasse
moet definieren. Die klasse heeft geen attributen anders dan referenties
naar zijn ouders en referentie(s) naar C. Zeer waarschijnlijk heeft deze
"koppelklasse" wel eigen gedrag.

Hoe zie jij deze kwestie? (Zie voor voorbeeld de posts hierboven).

Thanks,

Paul.
Frans Bouma
2003-12-31 09:32:53 UTC
Permalink
Post by Paul
[...knip]
Post by Frans Bouma
Een m:n relatie is altijd redundant, want in theorie is de
koppeltabel ook een entity, immers een entity == relation ==
verzameling attributes. Een m:n relation valt dus altijd uiteen in een
1:n en m:1 relatie, die lopen via een intermediate table/entity.
Het is interessanter om te kijken naar m:n relations die verlopen
via een intermediate table waar non-PK fields in zitten. Bv
Order-Product via OrderDetailRow. OrderDetailRow heeft meer informatie,
maar is ook de intermediate table tussen Order en Product.
Het is daarom inconsistent om te zeggen dat je 'dan maar wel' een
aparte entity herkent maar 'anders niet'. Want wat te doen wanneer je
een m:n relation 'objectified': Department - Employee hebben een m:n
relatie, fysiek gerealiseerd in de table DepartmentEmployee. Dit lijkt
een 'betekenisloze' intermediate table, echter wanneer de m:n relation
wordt geobjectified omdat je 'StartDate' wilt vastleggen, te weten de
datum wanneer een employee is begonnen met werken voor een department,
de intermediate table 1 column erbij krijgt (non-PK) maar dat deze eens
lege intermediate table ineens een volwaardige entiteit is (voor de
mensen die de 'betekenisloze' intermediate table niet voor vol
aanzagen).
Voor de record: een zuivere koppelentiteit is absoluut een volwaardige
entiteit, maar heeft geen aanvullende attributen behalve die van z'n
ouders. Vandaar de term "zuiver" [Finkelstein of Reingruber als ik me
niet vergis]. Een "onzuivere" koppelentiteit heeft extra attributen. In
het eerste geval _zou_ je ervoor kunnen kiezen om de n:m relatie te
implementeren middels lists binnen de klassen. Voor onzuivere
koppelentiteiten ligt een aparte klasse voor de hand.
precies, alleen om consequentie te behouden lijkt het mij althans
beter om altijd aparte classes for de intermediate tabel te gebruiken,
zoals ik aangaf.
Post by Paul
Het wordt interessanter wanneer je een zuivere koppelentiteit hebt,
waarbij de relatie tussen entiteit A en B betekenis heeft voor entiteit
C. Het lijkt me, en andere posters over deze kwestie, dat je dan toch
een nieuwe klasse moet definieren. Die klasse heeft geen attributen
anders dan referenties naar zijn ouders en referentie(s) naar C. Zeer
waarschijnlijk heeft deze "koppelklasse" wel eigen gedrag.
Je bedoelt dat de relatie tussen A en B semantische waarde heeft
voor C, maar dat C verder niet is gerelateerd aan A en B? Wat bedoel je
precies met 'referenties naar zijn ouders', want het relationele model
kent geen parent/child constructies (want (ok, niet zo briljant) je kunt
cycles maken in je relaties)

FB
--
Get LLBLGen Pro, the new O/R mapper for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Paul
2003-12-31 10:36:41 UTC
Permalink
"Frans Bouma" <***@xs4all.nl> schreef in bericht news:***@194.109.133.20...
[knip]
Post by Frans Bouma
Post by Paul
Voor de record: een zuivere koppelentiteit is absoluut een volwaardige
entiteit, maar heeft geen aanvullende attributen behalve die van z'n
ouders. Vandaar de term "zuiver" [Finkelstein of Reingruber als ik me
niet vergis]. Een "onzuivere" koppelentiteit heeft extra attributen. In
het eerste geval _zou_ je ervoor kunnen kiezen om de n:m relatie te
implementeren middels lists binnen de klassen. Voor onzuivere
koppelentiteiten ligt een aparte klasse voor de hand.
precies, alleen om consequentie te behouden lijkt het mij althans
beter om altijd aparte classes for de intermediate tabel te gebruiken,
zoals ik aangaf.
OK, dat is het overwegen waard. Het is altijd mogelijk dat wat nu een
eenvoudige koppeltabel is, later van meer attributen voorzien wordt.
Post by Frans Bouma
Post by Paul
Het wordt interessanter wanneer je een zuivere koppelentiteit hebt,
waarbij de relatie tussen entiteit A en B betekenis heeft voor entiteit
C. Het lijkt me, en andere posters over deze kwestie, dat je dan toch
een nieuwe klasse moet definieren. Die klasse heeft geen attributen
anders dan referenties naar zijn ouders en referentie(s) naar C. Zeer
waarschijnlijk heeft deze "koppelklasse" wel eigen gedrag.
Je bedoelt dat de relatie tussen A en B semantische waarde heeft
voor C, maar dat C verder niet is gerelateerd aan A en B? Wat bedoel je
precies met 'referenties naar zijn ouders', want het relationele model
kent geen parent/child constructies (want (ok, niet zo briljant) je kunt
cycles maken in je relaties)
De combinatie A-B heeft een associatie met C (ook many-to-many).
Bijvoorbeeld "A-B" 0..* <---> 0..* "C".

De referentie naar "ouders" komt door mijn opvoeding :-). Zonder gekheid:
ca. 10 jaar geleden leerde ik werken met een 4GL code generator (voor de IBM
AS/400). Het tool stelt modelleren van een probleem centraal. Dit gebeurt
door een datamodel op te zetten (vergelijkbaar met de NIAM methodiek). Aan
het model wordt functionaliteit toegekend middels overerving op
patternbasis. Koppeltabellen worden geimplementeerd middels een zogenaamde
"two parent child". Vandaar het gebruik van wat tool-specifiek jargon. Ik
bedoel simpelweg dat A-B alleen de sleutels van de bovenliggende tabellen
bevat.

Nu zie je ook de context van mijn oorspronkelijke vraag: ik ben gewend om
overerving toe te passen op datamodellen. Nu ik niet meer werk met dat tool,
probeer ik nog steeds hetzelfde te doen maar dan voor een OO-taal.
Frans Bouma
2003-12-31 12:00:52 UTC
Permalink
Post by Paul
[knip]
Post by Frans Bouma
Post by Paul
Het wordt interessanter wanneer je een zuivere koppelentiteit hebt,
waarbij de relatie tussen entiteit A en B betekenis heeft voor
entiteit C. Het lijkt me, en andere posters over deze kwestie, dat je
dan toch een nieuwe klasse moet definieren. Die klasse heeft geen
attributen anders dan referenties naar zijn ouders en referentie(s)
naar C. Zeer waarschijnlijk heeft deze "koppelklasse" wel eigen
gedrag.
Je bedoelt dat de relatie tussen A en B semantische waarde heeft
voor C, maar dat C verder niet is gerelateerd aan A en B? Wat bedoel je
precies met 'referenties naar zijn ouders', want het relationele model
kent geen parent/child constructies (want (ok, niet zo briljant) je
kunt cycles maken in je relaties)
De combinatie A-B heeft een associatie met C (ook many-to-many).
Bijvoorbeeld "A-B" 0..* <---> 0..* "C".
Ok, 'A-B' is objectified om als nieuwe 'entity' te dienen in de
relatie met C (niam) Het is natuurlijk dan wel de vraag of je semantisch
gezien A-B als een aparte entity moet erkennen in je OO model, immers als
A-B niet een 1:1 relatie hebben wordt het wat lastig.
Post by Paul
De referentie naar "ouders" komt door mijn opvoeding :-). Zonder
gekheid: ca. 10 jaar geleden leerde ik werken met een 4GL code generator
(voor de IBM AS/400). Het tool stelt modelleren van een probleem
centraal. Dit gebeurt door een datamodel op te zetten (vergelijkbaar met
de NIAM methodiek). Aan het model wordt functionaliteit toegekend
middels overerving op patternbasis. Koppeltabellen worden
geimplementeerd middels een zogenaamde "two parent child". Vandaar het
gebruik van wat tool-specifiek jargon. Ik bedoel simpelweg dat A-B
alleen de sleutels van de bovenliggende tabellen bevat.
ok :)
Die 4GL tool klinkt in theorie wel aardig moet ik zeggen, alleen
wat ik van de AS/400 gezien heb moet het wel een spartaanse GUI gehad
hebben ;) (sign-on)
Post by Paul
Nu zie je ook de context van mijn oorspronkelijke vraag: ik ben gewend
om overerving toe te passen op datamodellen. Nu ik niet meer werk met
dat tool, probeer ik nog steeds hetzelfde te doen maar dan voor een
OO-taal.
Ik denk dat het wat lastig wordt om wat je gewend bent 1:1 toe te
passen.

Frans
--
Get LLBLGen Pro, the new O/R mapper for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Paul
2003-12-30 20:33:00 UTC
Permalink
Stelling:

"Een logisch datamodel is een goed uitgangspunt om een conceptueel
objectmodel op te zetten"

Ben benieuwd :-)
Jaap Beetstra
2003-12-30 22:42:37 UTC
Permalink
Post by Paul
"Een logisch datamodel is een goed uitgangspunt om een conceptueel
objectmodel op te zetten"
Welk probleem probeer je op te lossen; waarom zou je wel een logisch
datamodel hebben maar geen conceptueel objectmodel? Als je bedoelt 'je kunt
het beste altijd eerst een logisch datamodel maken voor je een conceptueel
objectmodel gaat maken', dan ben ik het absoluut met je oneens. Het zijn
verschillende modellen met verschillende doelen.
Een datamodel structureert in de eerste plaats gegevens, een objectmodel
structureert in de eerste plaats gedrag. Die kunnen sterk overeenkomen, maar
dat hoeft niet; gedrag omvat iig meer. Bij sterk datagedreven applicaties
met weinig specifiek gedrag, zoals bijvoorbeeld een adressenlijstje, komen
deze redelijk overeen. Hoe complexer het gedrag is dat de applicatie moet
vertonen, hoe minder de twee modellen op elkaar lijken, en hoe eerder je
vastloopt met datagedreven-tools (zoals ms-access).
Een datamodel beschrijft alleen de onderste laag van een systeem; de
weergave, het interactie-verloop en de uit te voeren acties worden helemaal
niet meegenomen. In een (volledig) OO-model wel. Het hangt van je doel af
bij welk model het zwaartepunt ligt; Als het gaat om het organiseren van
gegevens zodat die voor veel sterk verschillende (maar op zichzelf
eenvoudige) toepassingen geschikt is, dan zal het zwaartepunt liggen op het
datamodel (of een datacentrisch objectmodel). Gaat het om een complexe
toepassing waarvan de (deel)gegevens redelijk zijn afgeschermd van andere
toepassingen, dan is het conceptuele objectmodel belangrijker.

Maar modelleer sowieso nooit om het modelleren; bedenk goed welke vraag je
model moet helpen beantwoorden, en modelleer met dat doel. Te vaak zie je
modellen die enorm uitgebreid zijn, maar waarin de echt moeilijke zaken
genegeerd worden. Een model is per definitie onvolledig, maar gelukkig kun
je kiezen waar je onvolledig bent.

Groet, Jaap
Frans Bouma
2003-12-31 09:47:14 UTC
Permalink
Post by Jaap Beetstra
Post by Paul
"Een logisch datamodel is een goed uitgangspunt om een conceptueel
objectmodel op te zetten"
Welk probleem probeer je op te lossen; waarom zou je wel een logisch
datamodel hebben maar geen conceptueel objectmodel? Als je bedoelt 'je
kunt het beste altijd eerst een logisch datamodel maken voor je een
conceptueel objectmodel gaat maken', dan ben ik het absoluut met je
oneens. Het zijn verschillende modellen met verschillende doelen.
klopt, echter het is maar hoe je tegen de koppeling van de 2
aankijkt. Als je middels OO met je data wilt werken, is het punt waar je
begint leidend voor de andere kant van de koppeling: maak je eerst de
classes dan moet je datamodel volgen, anders kom je in de problemen. Maak
je eerst het datamodel dan liggen de classes ook al min of meer vast, dwz
de classes die met de data werken.
Post by Jaap Beetstra
Een datamodel structureert in de eerste plaats gegevens, een objectmodel
structureert in de eerste plaats gedrag. Die kunnen sterk overeenkomen,
maar dat hoeft niet; gedrag omvat iig meer. Bij sterk datagedreven
applicaties met weinig specifiek gedrag, zoals bijvoorbeeld een
adressenlijstje, komen deze redelijk overeen. Hoe complexer het gedrag
is dat de applicatie moet vertonen, hoe minder de twee modellen op
elkaar lijken, en hoe eerder je vastloopt met datagedreven-tools (zoals
ms-access). Een datamodel beschrijft alleen de onderste laag van een
systeem; de weergave, het interactie-verloop en de uit te voeren acties
worden helemaal niet meegenomen. In een (volledig) OO-model wel. Het
hangt van je doel af bij welk model het zwaartepunt ligt; Als het gaat
om het organiseren van gegevens zodat die voor veel sterk verschillende
(maar op zichzelf eenvoudige) toepassingen geschikt is, dan zal het
zwaartepunt liggen op het datamodel (of een datacentrisch objectmodel).
Gaat het om een complexe toepassing waarvan de (deel)gegevens redelijk
zijn afgeschermd van andere toepassingen, dan is het conceptuele
objectmodel belangrijker.
Ik denk wel dat je wat op 1 hoop veegt. Je gaat volledig aan het
punt voorbij dat je wellicht een meerlagen structuur in je applicatie
hebt, waarbij de onderste laag (BL-facade, dal) op een OO manier toegang
biedt tot het relationele model in de database. Hoe je verder de rest
middels OO oplost, dus je BL classes en GUI, staat daar los van: die
consumeren je data-oriented laag.

Je stipt onbedoeld wellicht ;) wel een debat aan dat op dit moment
ook woedt in de microsoft.public.objectspaces newsgroup: domain model vs
service oriented model. Als je puur het domain model aanhangt dan mondt
dat uit in de persistency van de domain classes an sig. Kijk je anders
tegen de wereld aan (bv in een meer service oriented manier) dan ziet het
er heel anders uit.
Post by Jaap Beetstra
Maar modelleer sowieso nooit om het modelleren; bedenk goed welke vraag
je model moet helpen beantwoorden, en modelleer met dat doel. Te vaak
zie je modellen die enorm uitgebreid zijn, maar waarin de echt moeilijke
zaken genegeerd worden. Een model is per definitie onvolledig, maar
gelukkig kun je kiezen waar je onvolledig bent.
Ik zie modelleren meer als een op een abstracte manier inzicht
scheppen in de compliteit van je probleem. Daarom snap ik ook niet zo goed
waarom mensen E/R model gebruiken en niet NIAM/ORM bv.

FB
--
Get LLBLGen Pro, the new O/R mapper for .NET: http://www.llblgen.com
My .NET Blog: http://weblogs.asp.net/fbouma
Jaap Beetstra
2003-12-31 16:22:27 UTC
Permalink
Post by Frans Bouma
Post by Jaap Beetstra
Het hangt van je doel af
bij welk model het zwaartepunt ligt; Als het gaat om het organiseren
van gegevens zodat die voor veel sterk verschillende (maar op
zichzelf eenvoudige) toepassingen geschikt is, dan zal het
zwaartepunt liggen op het datamodel (of een datacentrisch
objectmodel). Gaat het om een complexe toepassing waarvan de
(deel)gegevens redelijk zijn afgeschermd van andere toepassingen,
dan is het conceptuele objectmodel belangrijker.
Ik denk wel dat je wat op 1 hoop veegt. Je gaat volledig aan het
punt voorbij dat je wellicht een meerlagen structuur in je applicatie
hebt, waarbij de onderste laag (BL-facade, dal) op een OO manier
toegang biedt tot het relationele model in de database. Hoe je verder
de rest middels OO oplost, dus je BL classes en GUI, staat daar los
van: die consumeren je data-oriented laag.
Goed punt; ik had het wel in gedachten, maar het stond erg door elkaar. Mijn
punt was dat naarmate BL+GUI complexer worden, de datalaag en daarmee het
datamodel (relatief) minder interessant worden. Bovendien kan, als er geen
noodzaak is voor een relationele database, de datalaag vaak volledig door
een framework verzorgd worden (bijv. standaard java serialization of
prevayler). Dat maakt een datamodel helemaal ondergeschikt.
Post by Frans Bouma
Je stipt onbedoeld wellicht ;) wel een debat aan dat op dit moment
ook woedt in de microsoft.public.objectspaces newsgroup: domain model
vs service oriented model. Als je puur het domain model aanhangt dan
mondt dat uit in de persistency van de domain classes an sig. Kijk je
anders tegen de wereld aan (bv in een meer service oriented manier)
dan ziet het er heel anders uit.
Dat debat zal ik zo eens bekijken; ter achtergrondinformatie: ik ga altijd
uit van domain models, eventueel gebruik van services is afgeleid.
Domain-driven Design van Eric Evans [ http://domaindrivendesign.org/ ] is
daarvoor wel leuk leesvoer.

Groet, Jaap
Frans Bouma
2003-12-31 16:31:30 UTC
Permalink
Post by Jaap Beetstra
Post by Frans Bouma
Post by Jaap Beetstra
Het hangt van je doel af
bij welk model het zwaartepunt ligt; Als het gaat om het organiseren
van gegevens zodat die voor veel sterk verschillende (maar op
zichzelf eenvoudige) toepassingen geschikt is, dan zal het
zwaartepunt liggen op het datamodel (of een datacentrisch
objectmodel). Gaat het om een complexe toepassing waarvan de
(deel)gegevens redelijk zijn afgeschermd van andere toepassingen,
dan is het conceptuele objectmodel belangrijker.
Ik denk wel dat je wat op 1 hoop veegt. Je gaat volledig aan het
punt voorbij dat je wellicht een meerlagen structuur in je applicatie
hebt, waarbij de onderste laag (BL-facade, dal) op een OO manier
toegang biedt tot het relationele model in de database. Hoe je verder
de rest middels OO oplost, dus je BL classes en GUI, staat daar los
van: die consumeren je data-oriented laag.
Goed punt; ik had het wel in gedachten, maar het stond erg door elkaar.
Mijn punt was dat naarmate BL+GUI complexer worden, de datalaag en
daarmee het datamodel (relatief) minder interessant worden. Bovendien
kan, als er geen noodzaak is voor een relationele database, de datalaag
vaak volledig door een framework verzorgd worden (bijv. standaard java
serialization of prevayler). Dat maakt een datamodel helemaal
ondergeschikt.
Mee eens, daarom zie ik een datalaag ook als 'consumpievoer' :) ->
je eigenlijke programma gebruikt het, maar is niet deel van de datalaag.
Alhoewel dat wel wat tegen het domainmodel ingaat overigens (althans, hoe
ik het begrepen heb: domain classes vormen je kern en die persist je en
omvatten je BL code)

FB

Loading...