- Jede Regel wird zu einer oder mehrerer Rollen in einer oder mehreren Compartments und bekommt noch einen Präfix Delete* Create* Synchronize*
- Damit haben alle Regeln auf jeden Fall schonmal einen einmaligen namen
- Andere Regeln wie Helper Regeln bekommen einen anderen Präfix und können als eigenes Compartment mit eigenen Rollen betrachtet werden
- Beim Erstellungsregeln werden über das Synchronisationscompartment Verlinkung zwischen den Teilprojekten erzeugt, d.h. sobald es eine Regel gibt die Gleichheit zwischen Objekten spezifiziert oder das erstellen Managed, werden automatischen die Verlinkungen auf Instanzebene mit erstellt. Diese müssen dannach nicht nochmal neu in Regeln spezifiziert werden
- Sobald sich die Synchronisationsregeln oder anderen Regeln ändern können diese zur Laufzeit ausgetauscht werden
- Falls die Namen identisch bleiben müssen nur die Regeln neu geladen werden und ersetzen sich gegenseitig
- Synchronization wird dann wieder auf den Punkt hergestellt und neue Modelle falls sie dazugekommen sind gleich mit integriert
- Möchte ich den Fall abbilden können, dass ich ein Element in einem Modelverbund löschen aber nicht die Verknüpften Elemente mitlösche (Nein: da dies zu unkontrollierten Problemen führt => maximal woanders als gelöscht markieren)
- darauf ergibt sich die Frage ob ich feingranulare Regeln überhaupt haben möchte oder ob mich eigentlich nur der Ansatz mit einer Regel die alles abbildet interessiert
# Running Example for this Webpage
- 3 Modelle Families, Persons und SimplePersons
- Konzept einer Person ist in jedem Modell verhanden
- Änderungen von einem Model müssen an die anderen propagiert werden
### Families (Model A)
```
class Family {
lastName: String
father: Member
mother: Member
sons: List[Member]
daughters: List[Member]
}
class Member {
firstName: String
address: String
birthday: Date
familyFather: Member
familyMother: Member
familySon: Member
familyDaughter: Member
}
```
### Persons (Model B)
```
class Person {
fullName: String
birthday: Date
}
class Male extends Person {}
class Female extends Person {}
```
### SimplePersons (Model C)
```
class SimplePerson {
completeName: String
address: String
male: Boolean
}
```
#### PhoneBook (Model D)
```
class PhoneBookEntry {
firstName: String
lstName: String
address: String
telefonNumber: String
}
```
# IDEAS WITH THOMAS
- Regeln sollten umkehrbar sein um gut abzubilden ist jedoch schon in diesem Beispiel nicht machbar
with (Member.firstName + " " + Family.lastName, Person.fullName, SimplePerson.completeName)
```
- Problem ist die Unterscheidung von männlich und weiblich, die kann ich hier nicht Abbilden, was natürlich die Problematik mit jeglicher Vererbung wieder mit sich bringt
## Attribute invariant
```
Attinv (Person, SimplePerson, Family o Member)
with (Member.firstName + " " + Family.lastName, Person.fullName, SimplePerson.completeName)
```
- Als Synchronisationsregel möglich jedoch zum Erzeugen nicht ausreichend
- Idee am Ende nur eine Regel Art aus der Synchronisations-, Lösch- und Erstellungsregeln erzeugt werden
# COMPLETE RULES
- Regeln, welche für Synchronization, Löschen und Erstellen verwendet werden können
- Vorteil:
- Kurze Regelschreibweise
- Sobald Elemente in der Regel vergessen werden fällt dies schneller auf
- Nachteil:
- keine feingranuale Spezifikation der Regeln
- Elementtypen werden für Löschen, Erstellen und Synchronisieren immer zusammenbetrachtet
### Complete Rule
- Code Generator muss Erstell-, Lösch- und Synchronisationsregeln aus einer so einer Regel generieren
- Erzeugung von Objekten kann anhand von Sync Regeln abgeleitet werden
- Trennung in primary Regeln und non-primary Regeln
- primary Regeln bestimmen Objekte zwischen Modellen eindeutig
-**Alte Idee:** Erzeugung von Objekten kann anhand der primary Regeln abgeleitet werden (Verkettung der primary Regeln für eindeutige Objekt erkennung zwischen Modellelementen verschiedener Modelle)
- Probleme
- Short Hand notationen für spezial Fälle die immer verwendet werden? **Brauchen wir das wirklich?**
- Grenzen von change Operatoren definieren **in folgenden Beispielen schon mit betrachtet**
- Wenn ich einen Modellverbund habe, wo alle Elemente auf die Regeln zutreffen in der Synchronisation enthalten sind, dann muss ich beim Insert nicht nach schon vorhandenen Elementen suchen, das würde nur bedeuten, dass das Element in dem Model wo es erstellt wurde schon existiert
- Deswegen macht die unterscheidung in primary und non-primary Regeln keine Sinn
- Außer man nutzt Primary Regeln für die integration von neuen Modellen
-**ALT Anfang**
- Fall (i): A (non-primary), B (non-primary), C (non-primary)
- Keine Erzeugung von Objekten in anderen Modellen, möglich da keine Primary Regeln
- Fall (ii): A (primary), B (non-primary), C (non-primary)
- firstName + ' ' + lastName == fullName == completeName (bestimmen die Abhängigkeiten zwischen den Modellen eindeutig)
- Namen als eindeutige Identifikation zwischen den Modellen angesehen
- Fall (iii): A (primary), B (primary), C (primary)
- firstName + ' ' + lastName == fullName == completeName && (address || birthday) (bestimmen die Abhängigkeiten zwischen den Modellen eindeutig)
- Namen in Kombination mit Geburtstag oder Adresse bestimmen die eindeutigen Referenzen zwischen den Modellen
-`instanceof` ist zwar Boolean aber not (instance of Female) ist nicht sinnvoll.
- Beispiel Operator: `case(b, {true: Persons!Female, false: Persons!Male})`
- General Operator: `case(o, {v_1:Model!Element1, ... v_n:Model!ElementN})` where Model is an arbitrary model and `Element1` till `ElementN` elements in this model. Moreover, $v_1$ till $v_n$ are arbitrary primitive (later object) values.
- Noch generellere wäre $v_1$ könnte $c.age>4 \land c.age<10$ sein, damit könnte ich Phasen oder Altersgruppen in Modell Instanzen synchronisieren
### Hilfs Funktion (Families) Mother<-> Father & Daughter <-> Son
- Anders wäre die Transformation von Persons und SimplePersons zu Families nicht möglich
- Funktion setzt Mütter zu Väter, Tochter zu Sohn und umgekehrt
- Methode müsste aufgerufen werden falls so eine Änderung in Persons oder SimplePersons auftritt
- Problem:
- da diese Änderungen auch in die Family Klasse übernommen werden müssen kann es sein das dort eine Vater Relation überschrieben wird oder eine Mutter Relation überschrieben wird, da es sich um opposite Relationen handeln kann
- Dies würde zu einer nicht mehr handhabbaren Veränderung führen
- primary Operator, um zu sehen welche Regeln nötig sind um ein Model in die existierende Synchronisation einzubeziehen
- hier wäre nur Model B notwendig, da es das einzige interagierende in der `primary` Regel ist
- Erweiterungsregel könnte als neues Compartment einfach mit eingeladen werden
- Möglich Regel zu neuer großer Regel zu kombinieren und dann mit einmal neu einzuladen (jedoch dann nicht mehr ganz klar, welches Model neu ist, und wie dies gleich in die existierende Synchronisation integriert wird)
### Delete Phone Book Model from Synchronization
-`delete PhoneBook` könnte genutzt werden um ein Model komplett aus der Synchronisation zu löschen
- Regeln würden weiter exisiteren jedoch würde er intern alles davon betroffene ignorieren
# SPLIT INTO 3 RULE TYPES
- Synchronizations-, Lösch und Erstellungsregeln einzeln definieren und dann in dazugehörigen Compartments umsetzen
- Vorteil:
- Feingranulare Spezifikation der Regeln in der Synchronisationssprache
- Element typen können speziell aus dem Löschprozess rausgehalten werden
- Nachteil:
- Mehr schreib Aufwand für Regel Spezifikation
- Sobald Regeln vergessen werden können diese nicht umgesetzt werden
## Synchronization Rules
- 3 Ideen wie Synchronisationsregeln aussehen könnten die 3. ist dabei die vermutlich Eleganteste
- die 2. ist nur abgewandelt zur 1. und eigentlich sinnlos
### Idee 1
- Jede Regel sagt genau welche anderen Objekte sie verändert und sorgt dafür das nicht das gleich Model nochmal angefasst wird
- 1 zu n
```
syncRule syncFirstNameFromMember {
from
a : Families!Member (firstName) //variablen Änderung auf die diese Regel reagieren soll
in
b : Persons!Person (
b.fullName <- a.firstName + ' ' + b.lastName //idee in part darf nur von from part beeinflusst werden und nicht von anderem in part
),
c : SimplePersons!SimplePerson (
c.completeName <- a.firstName + ' ' + c.lastName //darf nicht von b beeinflusst werden
)
}
syncRule syncLastNameFromFamily {
from
a : Families!Family (lastName) //variablen Änderung auf die diese Regel reagieren soll
in
b : Persons!Person (
b.fullName <- b.firstName + ' ' + a.lastName
),
c : SimplePersons!SimplePerson (
c.completeName <- c.firstName + ' ' + a.lastName
)
}
syncRule syncFullNameFromPerson {
from
b : Persons!Person (fullName)
in
a : Families!Member (
a.firstName <- b.firstName
),
d : Families!Family (
d.lastName <- b.lastName
),
c : SimplePersons!SimplePerson (
c.completeName <- b.fullName
)
}
syncRule syncCompleteNameFromSimplePerson {
from
c : SimplePersons!SimplePerson (completeName)
in
a : Families!Member (
a.firstName <- c.firstName
),
d : Families!Family (
d.lastName <- c.lastName
),
b : Persons!Person (
b.fullName <- c.completeName
)
}
```
### Idee 2
- Nachteil Änderungen werden auch im eigenen Model nochmal durchgeführt, da die Funktion syncNames nicht unterscheidet von welchem Element sie aufgerufen wird
- diese Regeln Rufen immer nur die Synchonisationsfunktion auf und bestimmen selbst nur welches Änderung als Event fungiert
- 1 zu n mit event trigger
```
syncRule syncCompleteNameFromSimplePerson {
from
c : SimplePersons!SimplePerson (completeName)
do
syncNameFunction (c.firstName : String, c.lastName : String) // wieder mit Nutzung der Hilfsfunktionen
}
syncRule syncFirstNameFromMember {
from
a : Families!Member (firstName) //variablen Änderung auf die diese Regel reagieren soll
do
syncNameFunction (a.firstName : String, a.lastName : String) // wieder mit Nutzung der Hilfsfunktionen
}
syncRule syncLastNameFromFamily {
from
a : Families!Family (lastName) //variablen Änderung auf die diese Regel reagieren soll
do
syncNameFunction (a.firstName : String, a.lastName : String) // wieder mit Nutzung der Hilfsfunktionen
}
syncRule syncFullNameFromPerson {
from
b : Persons!Person (fullName)
do
syncNameFunction (b.firstName : String, b.lastName : String) // wieder mit Nutzung der Hilfsfunktionen
}
```
- diese Regel kümmert sich um die Durchführung der Synchronisation und wird nur von denen davor aufgerufen wenn eine Änderung wo eintritt