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.
Genau. Deshalb mein Vorschlag, die Adoption erst hinterher zu machen. Das geht in dem Fall ganz gut.
Zitat:
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:
- adopted - zeigt Adoptiveltern an
- birth - zeigt biologische Eltern an
- foster - zeigt an, dass das Kind in einer Pflegefamilie oder Vormundschaft war
- sealing - zeigt an, dass das Kind an andere als seine leibliche Eltern gesiegelt wurde (speziell bei Mormonen)
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.
Zitat:
Erklär mir deine Überlegung mit "TAdoption" bitte nochmal genauer.
Ein TGenealogyEntity kann Kinder adoptieren. Deshalb bietet diese Klasse eine Methode adopt() an. Diese Methode erstellt ein neues TAdoption-Objekt, weist die Werte zu und träge eine Referenz in den Adoptivling, sowie in die Adoptiveltern (TGenealogyEntity also entweder eine TPartnership oder eine TPerson) ein.
Zitat:
[INDENT]
- DATE_APPROXIMATED - Datum, genähert
- ABT = “um” oder “circa”
- CAL = das Datum ist nicht exakt
- EST = mathematisch errechnet, z. B. durch ein Ereignis und ein Alter. auf der Basis eines Algorithmus und eines anderen Datums geschätzt.
ABT entspricht "uncertain". CAL müsste man noch einführen. EST versteh ich nicht ganz. Das läuft doch auch wieder auf sowas wie CAL hinaus.
Zitat:
[*]DATE_EXACT - exaktes Datum (z.B. 01.01.2000)
ist drin.
Zitat:
[*]DATE_PERIOD - Datum, Zeitspanne
Wenn man sowas braucht, sollte man daraus wohl eher nen weiteren Typen machen. TVagueTimePeriod, das zwei TVagueDate-Werte enthält.
Zitat:
[*]DATE_PHRASE - beliebige Aussage zum Datum, sozusagen benutzerdefiniert
Wenn man das braucht, kann mans leicht ergänzen. Einfach nen zusätzlichen String-Wert.
Zitat:
[*]
DATE_RANGE - Datum, zeitlich eingegrenzt
- AFT = Das Ereignis fand nach dem angegebenen Datum statt
- BEF = Das Ereignis fand vor dem angegebenen Datum statt
- BET Datum AND Datum = Das Ereignis fand irgendwann zwischen dem 1. und dem 2. Datum statt
[/LIST]
Before und after ist drin. Between fehlt noch. Dazu braucht man nen weiteren TDate-Wert, nen Weiteren enum-Wert und ein paar weiter Invarianten.
Zitat:
Was eine
Exception ist weiß ich, aber was ist das:
Exception: EMarriageImpossibleException;
bzw. was hast du Dir darunter vorgestellt?
Eine
Exception ist letztendlich ja auch ne Klasse. Die von dir zitierte Zeile tut also nix anderes als eine Variable von der Klasse EMarriageImpossibleException deklarieren. Instanziiert wird die
Exception dann weiter unten. EMarriageImpossibleException ist also eine Klasse, die von
Exception erbt und ggf. zusätzliche Attribute und Methoden enthält. Wie im Quelltext ersichtlich hat sie eine Property namens "ConflictingMarriage".
Zitat:
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!
Nein. Das macht Probleme.
Delphi-Quellcode:
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);
Die Folge:
- 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.
Zitat:
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!
Sehr guter Punkt! Normalerweise hat man diese Probleme nicht, weil man Kreuzreferenzen eh vermeiden sollte. Die Dinger sind eigentlich schlecht. Ziemlich schlecht. Wie in vorherigem Post erläutert, brechen wir diese Regel hier bewusst [1] um anderen Problemen aus dem Weg zu gehen. Also: Wir haben erstmal dieses Problem, dass wir Kreuzreferenzen haben und der Compiler die nicht will. Da müssen wir was dagegen tun.
Die einfachste Lösung ist, das alles in eine
Unit zu packen und Forward-Deklarationen zu verwenden:
Delphi-Quellcode:
TFoo = class; // forward declaration
TBar = class
foo: TFoo;
end;
TFoo = class
bar: TBar;
end;
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.
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
Pseudo-Templates einsetzen.
[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