|
![]() |
|
Registriert seit: 14. Apr 2004 Ort: Karlsruhe 318 Beiträge Delphi 2010 Architect |
#1
Lieber Christian,
das ist ja ne Menge. Was die Verwandtschaftsverhältnisse betrifft, so hast du meines Wissens nach alle Eventualitäten genannt. Das ist für den Anfang ganz schön viel. Den Vorschlag einer Adoption eine eigene Klasse zu widmen finde ich sehr gut, auch, wenn die gängigen Genealogieprogramme Adoptiveltern zulassen. Es wird eine neue Familie (TPartnership) erzeugt und das Kind hinzugefügt. Diesem wird dann der Status "adoptiert" zugeordnet. Im Gedcom-Standard ist diese Eigenschaft unter "PEDIGREE_LINKAGE_TYPE" definiert. Siekann folgende Werte annehmen: Erklär mir deine Überlegung mit "TAdoption" bitte nochmal genauer. Zu TVagueDate Auch diese Überlegung ist richtig. Aber die Sache verkompliziert sich noch, da hier der Gedcom-Standard ebenfalls detailliertere Optionen bietet:
![]() Das Beispiel, das eine Person eine weitere Person heiratet ist auch super verständlich. Warum kompliziert, wenns auch einfach geht ![]() Was eine Exception ist weiß ich, aber was ist das: Exception: EMarriageImpossibleException; bzw. was hast du Dir darunter vorgestellt? Selbst wenn eine Person bereits ein Vater zugewiesen ist, so muss ein erneuter Aufruf von AddFather nicht zwangsläufig zu einem Fehler führen, dann wird der vorhandene Vater einfach durch einen Anderen ersetzt! Alle genannten Invarianten leuchten mir ein, stimme Dir zu! Eine zusätzliche Invariante wäre z.B. noch So das sind erstmal meine Anmerkungen zu deinem letzten Beitrag. Eine ganz blöde Frage noch. Ich implementiere die Klasse TPerson und vorher TPartnership, da diese ja innerhalb der Klasse TPerson verwendet wird. Nun ruft aber die Klasse TPartnership innerhalb eventuell auch einmal TPerson auf. Beim Kompilieren kommt es zu einem Abbruch, logisch, woher soll TPartnership TPerson kennen, wenn es erst danach implementiert ist. Verstehst du? Gibts da ne Lösung für, bestimmt, nur ist sie mir nicht geläufig! VG hansklok |
![]() |
Registriert seit: 9. Mai 2005 Ort: Nordbaden 925 Beiträge |
#2
Was die Verwandtschaftsverhältnisse betrifft, so hast du meines Wissens nach alle Eventualitäten genannt. Das ist für den Anfang ganz schön viel.
![]() Den Vorschlag einer Adoption eine eigene Klasse zu widmen finde ich sehr gut, auch, wenn die gängigen Genealogieprogramme Adoptiveltern zulassen. Es wird eine neue Familie (TPartnership) erzeugt und das Kind hinzugefügt. Diesem wird dann der Status "adoptiert" zugeordnet. Im Gedcom-Standard ist diese Eigenschaft unter "PEDIGREE_LINKAGE_TYPE" definiert. Siekann folgende Werte annehmen:
![]() Erklär mir deine Überlegung mit "TAdoption" bitte nochmal genauer.
![]() [INDENT]
![]() [*]DATE_EXACT - exaktes Datum (z.B. 01.01.2000)
![]() [*]DATE_PERIOD - Datum, Zeitspanne
![]() [*]DATE_PHRASE - beliebige Aussage zum Datum, sozusagen benutzerdefiniert
![]() [*]DATE_RANGE - Datum, zeitlich eingegrenzt
[/LIST] ![]() Was eine Exception ist weiß ich, aber was ist das: Exception: EMarriageImpossibleException;
bzw. was hast du Dir darunter vorgestellt?
![]() Selbst wenn eine Person bereits ein Vater zugewiesen ist, so muss ein erneuter Aufruf von AddFather
nicht zwangsläufig zu einem Fehler führen, dann wird der vorhandene Vater einfach durch einen Anderen ersetzt!
Delphi-Quellcode:
Die Folge:
Charlie := Alice.giveBirthToChildFrom(Bob, Now);
Doris := Alice.giveBirthToChildFrom(Bob, Now); // Charlie und Doris haben beide als Vater Bob // jetzt fällt uns auf, dass wir uns verlesen haben. Charlie stammt aus ner früheren Ehe: Charlie.addFather(Archibald); - Auch Doris ist jetzt ein Kind von Archibald - Alice ist nicht mehr mit Bob verheiratet o.ä. - Alice ist nun zwei Mal mit Archibald verheitatet/"verpartnert"; womöglich sogar nach Archibalds Tod. Deshalb muss hier ne Exception geworfen werden. ![]() Eine ganz blöde Frage noch. Ich implementiere die Klasse TPerson und vorher TPartnership, da diese ja innerhalb der Klasse TPerson verwendet wird. Nun ruft aber die Klasse TPartnership innerhalb eventuell auch einmal TPerson auf. Beim Kompilieren kommt es zu einem Abbruch, logisch, woher soll TPartnership TPerson kennen, wenn es erst danach implementiert ist. Verstehst du? Gibts da ne Lösung für, bestimmt, nur ist sie mir nicht geläufig!
Die einfachste Lösung ist, das alles in eine Unit zu packen und Forward-Deklarationen zu verwenden:
Delphi-Quellcode:
Das ist nicht allzu schön, allerdings sind die Klassen TPerson und TPartnership eh schon recht stark aneinander gekoppelt (was auch nicht schön ist, aber nicht besser geht). Man muss eben Kompromisse eingehen. Das ist normal.
TFoo = class; // forward declaration
TBar = class foo: TFoo; end; TFoo = class bar: TBar; end; BTW. Bevor ichs vergesse. Das wollte ich gestern schon schreiben: Hier ist Typsicherheit recht wichtig. Du solltest also besser statt normalen TObjectLists, typisierte Listen verwenden. Also entweder ein neues Delphi einsetzen, das Generics kann oder von TObjectList ableiten und eine TPersonList, etc. draus machen oder ![]() [1] Softwareentwicklung ist IMHO das ständige Ausbalancieren von Prinzipien und Daumenregeln. Die oberste Daumenregel heißt dabei "Wenn du das Gefühl hast, eine Regel brechen zu müssen, tu es. Wundere dich aber nicht über die Konsequenzen." Da sich viele Regeln widersprechen, muss man diese Regel ziemlich häufig anwenden. Immer ein Mittelmaß finden... mfg Christian
Kaum macht man's richtig, schon klappts!
|
![]() |
Registriert seit: 14. Apr 2004 Ort: Karlsruhe 318 Beiträge Delphi 2010 Architect |
#3
![]() So kannst du das auch machen. Nur musst du dann Unterscheiden zwischen TPartnership-Objekten, die wirklich eine Partnerschaft darstellt, wobei ein Teil aber unbekannt ist und Einzelpersonen, die Kinder adoptieren. Da müsste man überlegen, was fachlich besser passt. Möglich ist aber beides.
![]() Between fehlt noch. Dazu braucht man nen weiteren TDate-Wert, nen Weiteren enum-Wert und ein paar weiter Invarianten.
Der Rest leuchtet mir ein. Nun ist mir was Ein- bzw. Aufgefallen. Heirat, Scheidung, Geburt, Tod, Jugendweihe, Taufe etc. sind ja alles Ereignisse, nennen wir sie TEvents. Jedes Event besitzt ein Start- und ein Enddatum. Wäre es also nicht günstiger eine Klasse TEvents zu erstellen und ihr widerrum eine Variable zuweisen, die ihr sagt um welches Event es sich handelt (Hochzeit, Taufe...). So wird das auch im GEDCOM-Standard bearbeitet. Und nochmal zu einer alten Frage von dir, war ich nur 15 Personen im Stammbaum darstellen will. Wenn nach mir ginge, gern auch mehr Generationen, da ist jedoch das Problem mit der Bildschirmbreite & -höhe, dass muss man halt bei der erstellung eines solchen Controls beachten. Wie verfahren wir weiter? Neue Gedankengänge oder Geistesblitze? HG hansklok Geändert von hansklok ( 2. Sep 2010 um 17:32 Uhr) |
![]() |
Registriert seit: 9. Mai 2005 Ort: Nordbaden 925 Beiträge |
#4
![]() So kannst du das auch machen. Nur musst du dann Unterscheiden zwischen TPartnership-Objekten, die wirklich eine Partnerschaft darstellt, wobei ein Teil aber unbekannt ist und Einzelpersonen, die Kinder adoptieren. Da müsste man überlegen, was fachlich besser passt. Möglich ist aber beides.
- Adoption ist keine Partnership, sondern was anderes ==> ne eigene Klasse - Eine Adoption ist eine Beziehung zwischen einem Adoptivling und einem Adoptierer - Adoptierer kann eine Einzelperson sein, aber auch eine "Familie" ==> eine TPartnership - TGenealogyEntity ist Superklasse zu TPartnership und TPerson ==> Alle Objekte dieser Klasse - seien es jetzt TPersons oder TPartnerships - können adoptieren Damit geschieht Adoption folgendermaßen: - TGenealogyEntity hat ne Methode adopt(TPerson) - adopt() erzeugt ein neues TAdoption-Objekt und registriert es bei Adoptivling und bei Adoptierer jeweils in einer Liste. Möglichkeit b) - Eine Adoption ist nur eine weitere Art Partnership; dazu verpasst du TPartnership ein typ-Feld, das es als Adoption ausweist; alternativ kannst du das auch tun, indem du TAdoption von TPartnership ableitest - diese Partnership hat nun den Adoptivling als Kind in der Liste Hier müssen aber ein paar Details berücksichtigt werden: - Die Adoption-Partnership kann eine Person enthalten oder auch zwei; man kann ja auch als Einzelperson Kinder adoptieren - Du musst aufpassen, dass du die Adoption-Partnerships nicht mit den normalen Partnerships mischst. Du kannst sie nicht mischen, weil du sonst nicht zwischen eigenen und adoptierten Kindern einer Partnerhip unterscheiden könntest. Du brauchst also für das verheiratete Ehepaar Alice und Bob, die bereits ihren biologischen Sohn Charlie haben eine weitere Partnership von Alice und Bob, wenn diese Doris adoptieren. - Dadurch hast du eine bisher bestehende Invariante verändert. Bisher gilt ja, dass zwei Personen zu einem Zeitpunkt nur eine Partnership miteinander haben können. Sie können also nicht gleichzeitig zweimal miteinander verheiratet sein oder verheiratet sein, und gleichzeitig miteinander(!) uneheliche Kinder zeugen. Jetzt hast du ne Ausnahme in der Invariante drin. Bei Adoptionen geht sowas nämlich doch. - Eine weitere Invariante kriegt ne Ausnahme: Bisher gilt: Eine Partnership gesteht immer aus zwei Personen. Es ist möglich dass eine der beiden unbekannt ist, aber es sind immer zwei. Jetzt kann es sein, dass eine Partnership aus nur einer Person besteht (was den Namen Partnersip ad absurdum führt). - vielleicht gibts noch anderes zu beachten; wer weiß... ==> IMHO ist Variante b) komplizierter, da die Invarianten komplizierter werden und schlechter nachvollziehbar/lesbar, weil Partnership auch Einzelpersonen beschreiben kann und nun auch Überlappungen existieren können. Ich würde also Variante a) empfehlen. ![]() ![]() Between fehlt noch. Dazu braucht man nen weiteren TDate-Wert, nen Weiteren enum-Wert und ein paar weiter Invarianten.
- wenn uncertainty = ucRange ist, dann ist Value2 > Value1 ![]() Nun ist mir was Ein- bzw. Aufgefallen. Heirat, Scheidung, Geburt, Tod, Jugendweihe, Taufe etc. sind ja alles Ereignisse, nennen wir sie TEvents. Jedes Event besitzt ein Start- und ein Enddatum. Wäre es also nicht günstiger eine Klasse TEvents zu erstellen und ihr widerrum eine Variable zuweisen, die ihr sagt um welches Event es sich handelt (Hochzeit, Taufe...). So wird das auch im GEDCOM-Standard bearbeitet.
![]() ![]() Und nochmal zu einer alten Frage von dir, war ich nur 15 Personen im Stammbaum darstellen will. Wenn nach mir ginge, gern auch mehr Generationen, da ist jedoch das Problem mit der Bildschirmbreite & -höhe, dass muss man halt bei der erstellung eines solchen Controls beachten.
![]() Wie verfahren wir weiter?
Das kannst du direkt im Diagramm tun. Wenn du aus irgendwelchen Gründen nicht so gerne das Zeug im Diagramm machen willst, schreib den interface-Teil des Codes. Also Felder und Methoden. Wenn du mir das Ergebnis zeigst, kann ich drüber gucken, eventuelle Probleme anmerken und danach beschäftigen wir uns mit der Datensepicherung. mfg Christian
Kaum macht man's richtig, schon klappts!
|
![]() |
Registriert seit: 14. Apr 2004 Ort: Karlsruhe 318 Beiträge Delphi 2010 Architect |
#5
...also nun hab ich das verstanden und Möglichkeit A scheint mir auch besser und vor allem weniger anfällig für Fehler.
Ich habe einen Entwurf für eine Event-Oberklasse gemacht, von ihm sind dann neue Objekttypen (z.B. Scheidung, Hochzeit etc.) abgeleitet. ![]() Kennst du Scrollbars?
![]() LG hansklok |
![]() |
Registriert seit: 9. Mai 2005 Ort: Nordbaden 925 Beiträge |
#6
Ich habe einen Entwurf für eine Event-Oberklasse gemacht, von ihm sind dann neue Objekttypen (z.B. Scheidung, Hochzeit etc.) abgeleitet.
![]() Weitere Daten kannst du - wenn nötig - entweder zu TPerson (oder andere Klassen) packen oder in ne generische Notizklasse auslagern. Du brauchst nicht zu allem, was dir einfällt, ne eigene Klasse. Alles weitere in der Antwort auf deine Mail. ![]() ![]() Kennst du Scrollbars?
![]() mfg Christian
Kaum macht man's richtig, schon klappts!
|
![]() |
Registriert seit: 14. Apr 2004 Ort: Karlsruhe 318 Beiträge Delphi 2010 Architect |
#7
Aus welchem Grund? Tu sowas nur, wenn du einen Vorteil daraus hast. Das macht die Sache erstmal deutlich komplizierter. Damit du das wirklich nutzen kannst, müsstest du Polymorphie einsetzen können und da sehe ich momentan keine sinnvolle Möglichkeit. Modelliere wirklich nur das, was du auch brauchst. Ansonsten machst du dir nur das Leben schwer:
![]() Weitere Daten kannst du - wenn nötig - entweder zu TPerson (oder andere Klassen) packen oder in ne generische Notizklasse auslagern. Du brauchst nicht zu allem, was dir einfällt, ne eigene Klasse. Eine Geburt oder eine Hochzeit sind genauso Ereignisse wie eine Taufe oder eine Scheidung. Nicht immer gibt es eindeutige Belege über den Zeitpunkt eines Ereignisses, deshalb können auch Zeitspannen (z.B. zwischen dem 31.01.2009 und 03.04.2009) angegeben werden. Alle diese exemplarischen Ereignistypen haben dieselben Standardeigenschaften (z.B. Datum, Ort). Deshalb habe ich neue Klassen von TEvent abgeleitet und beispielsweise bei TMarriage noch den Taufpaten als Eigenschaft hinzugefügt, verstehst du? Ein Umzug, also ein Wohnortwechsel ist genauso ein Ereignis wie z.B. eine Volkszählung. Das war mein Hintergrundgedanke bei der ganzen Sache. Erkläre mir bitte nochmal deine Alternative genauer! HG hansklok |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |