Wikifunctions:Darstellung von Identität
Zusammenfassung
Wir verwenden Identität häufig im Wikifunctions-Datenmodell, beispielsweise in Z4K1, Z8K5, Z40K1 und anderen. Es wäre sinnvoll, sie in einigen unserer bestehenden Typen zu verwenden, wo wir dies derzeit nicht tun, beispielsweise in Implementation (Z14), Natural language (Z60) und Programming language (Z61). Auch geplante Typen, insbesondere Aufzählungen, wie grammatikalische Funktionen, erfordern Identität.
Darüber hinaus kann eine der vorgeschlagenen Lösungen auch eine seit langem bestehende Frage zu optionalen Schlüsselwerten beantworten.
In diesem Dokument werden vier Vorschläge dargelegt:
- Ein Typ für Identität
- Ein generischer Typ für Identität
- Ein boolescher Schlüssel in Schlüsseln
- Ein Schlüssel mit einer Liste von Markierungen in Schlüsseln
Verwandte Fehler
Fehler, die mit diesem Design zusammenhängen:
- T282716: Modell der ZObjekte: Erstellung eines Typs für die Identität
- T320557: Das Hinzufügen eines Identitätsschlüssels zum Funktionsmodell für ZImplementierungen in Erwägung ziehen
- T282062: Modell der ZObjekte: Zu Z3 einen Schlüssel hinzufügen, um einen Schlüssel als optional zu markieren
- T290996: Optionale Schlüssel im Orchestrierer unterstützen
- T296755: Aktuelle Relevanz von SELF_REFERENTIAL_KEYS prüfen und entfernen, wenn nicht erforderlich
- T304682: Funktionsschema: Erforderliche Schlüssel für benutzerdefinierte Prüfer korrigieren
- T315914: Diskutieren, ob wir den Fall berücksichtigen müssen, dass neue Schlüssel zu vorhandenen Typen mit Instanzen hinzugefügt werden
- T296400: Wenn der Schlüssel eines Objekts für einen Typ ist, wird die UX standardmäßig auf eine Referenz und nicht auf eine Instanz gesetzt
- T343614: Prüfung von Typen sollte die Identität prüfen
Was ist Identität überhaupt?
Identität ist ein Mechanismus, um zu erfassen, was ein bestimmtes Objekt ist. Einige Typen, wie Zeichenketten oder Zahlen, benötigen keinen zusätzlichen Schlüssel, da ihr Wert ihre Identität ist. Bei anderen Typen ist es jedoch nicht so einfach. Ein Beispiel sind die beiden booleschen Werte wahr und falsch, die strukturell nicht unterscheidbar sind. Indem wir das Objekt auf Wikifunctions persistent speichern, erhält es eine ZID, und wir verwenden diese ZID, um die beiden Werte zu unterscheiden. Darüber hinaus können wir jedem Objekt Namen und Beschreibungen hinzufügen (was es Benutzern effektiv ermöglicht, die Bedeutung der gegebenen Objekte zu verstehen).
Durch die Verwendung von Identität können wir außerdem sicherstellen, dass wir Herren unseres eigenen Schicksals sind: Anstatt uns bei Sprachen auf eine externe Autorität wie die ISO zu verlassen, können wir selbst entscheiden und kontrollieren, welche Sprachen wir unterstützen möchten, welche Sprachen wir differenzieren, etc.
Ein weiterer Vorteil der Identität besteht darin, dass dies die einzige Möglichkeit ist, den Z2 eines bestimmten Objekts zu erhalten und somit auf den Namen und die Beschreibung des Objekts zuzugreifen.
Identitätsschlüssel können manchmal einfacheren, geradlinigeren Quellcode unterstützen. Beispielsweise wurde T321998 (der übergeordnete Task zu T320557) durch den Wunsch motiviert, die Implementierungs-ID in der Metadatenzuordnung für den Orchestrierer sauberer aufzuzeichnen.
Für alle Vorschläge erforderliche Arbeit
- Sobald die Identität verfügbar ist, kann die Standardkomponente diese Informationen verwenden, um zu entscheiden, ob Referenzen anstelle von Literalen ausgewählt werden sollen.
- Änderungen an der Standardkomponente, sodass die Auswahl entsprechend eingeschränkt wird.
- Optional: Prüfer könnten etwas rationalisiert werden.
Laufendes Beispiel
Als laufendes Beispiel verwenden wir Boolean (Z40).
So sieht die Definition von Z40/boolescher Wert derzeit aus:
{
"Type": "Type",
"Identity": "Boolean",
"Keys": ["Key",
{
"Type": "Key",
"Key type": "Boolean",
"Key ID": "Z40K1",
"Names": [ … ]
}
],
"Validator": …
}
|
{
"Z1K1": "Z4",
"Z4K1": "Z40",
"Z4K2": ["Z3",
{
"Z1K1": "Z3",
"Z3K1": "Z40",
"Z3K2": "Z40K1",
"Z3K3": [ … ]
}
],
"Z4K3": …
}
|
Es ist völlig implizit, dass der Schlüssel die Identität definiert. Wir können versuchen, dies zu erraten, da der Schlüsseltyp boolesch ist, also der Typ, den wir definieren, aber das kann eine falsche Annahme sein.
Ein boolescher Wert für wahr sieht derzeit wie folgt aus:
{
"Type": "Boolean",
"Identity": "True"
}
|
{
"Z1K1": "Z40",
"Z40K1": "Z41"
}
|
Vorschlag 1: Ein Typ für Identität
Wir führen einen neuen Typ ein: Z91/Identität. Z91 wird auf den Schlüssel angewendet, um anzugeben, dass dieser Schlüssel eine Identität ist.
Definition boolescher Werte
Unterschiede sind markiert.
{
"Type": "Type",
"Identity": "Boolean",
"Keys": ["Key",
{
"Type": "Key",
"Key type": "Identity",
"Key ID": "Z40K1",
"Names": [ … ]
}
],
"Validator": …
}
|
{
"Z1K1": "Z4",
"Z4K1": "Z40",
"Z4K2": ["Z3",
{
"Z1K1": "Z3",
"Z3K1": "Z91",
"Z3K2": "Z40K1",
"Z3K3": [ … ]
}
],
"Z4K3": …
}
|
Es gibt einen neuen Typ, der die gleiche Definition wie Z9 hätte. Der Wert für true (Z41) würde also wie folgt aussehen.
{
"Type": "Boolean",
"Identity": {
"Type": "Identity",
"Reference": "True"
}
}
|
{
"Z1K1": "Z40",
"Z40K1": {
"Z1K1": "Z91",
"Z91K1": "Z41"
}
}
|
Erforderliche Arbeit
- Identitätstyp hinzufügen
- Typen und alle Werte, die Identität nutzen, anpassen
- Wahrscheinlich wäre eine maßgeschneiderte Komponente zum Bearbeiten von Z91 erforderlich (eine einfache, die ZReferenz sehr ähnlich ist, aber die Auswahlmöglichkeiten einschränkt)
- Erfordert eine Anpassung des Back-Ends für jeden Typ, der Identität verwendet, da sich die Instanzen geändert haben
Vorteile
- Keine Änderungen am Typ Typ
Nachteile
- Wir müssten alle vorhandenen Werte mit einer Identität und alle Typen, die eine Identität verwenden, ändern. Aber besser jetzt als später.
- Sofern wir keine maßgeschneiderte Benutzeroberfläche erstellen, hätten wir beim Erstellen von Instanzen dieses Typs keine Anleitung.
- Ein Prüfer würde jedoch Fehler abfangen
- Prüfer müssen an den neuen Typ angepasst werden. Die Arbeit muss mit der Umstellung der einzelnen Typen synchronisiert werden.
Vorschlag 2: Ein generischer Typ für Identität
Wir führen einen generischen Typ für die Identität ein, Z891. Z891 nimmt den Typ an, den der Identitätsschlüssel erwartet und gibt etwas wie Z91 aus Vorschlag 1 zurück, aber typensicher.
Definition boolescher Werte
Unterschiede sind markiert.
{
"Type": "Type",
"Identity": "Boolean",
"Keys": ["Key",
{
"Type": "Key",
"Key type": {
"Type": "Function call",
"Function": "Identity",
"Type": "Boolean"
},
"Key ID": "Z40K1",
"Names": [ … ]
}
],
"Validator": …
}
|
{
"Z1K1": "Z4",
"Z4K1": "Z40",
"Z4K2": ["Z3",
{
"Z1K1": "Z3",
"Z3K1": {
"Z1K1": "Z7",
"Z7K1": "Z891",
"Z891K1": "Z40"
},
"Z3K2": "Z40K1",
"Z3K3": [ … ]
}
],
"Z4K3": …
}
|
Es gibt einen neuen Typ, der die gleiche Definition wie Z9 hätte. Der Wert für Z41/wahr würde also wie folgt aussehen.
{
"Type": "Boolean",
"Identity": {
"Type": {
"Type": "Function call",
"Function": "Identity",
"Type": "Boolean"
},
"Reference": "True"
}
}
|
{
"Z1K1": "Z40",
"Z40K1": {
"Z1K1": {
"Z1K1": "Z7",
"Z7K1": "Z891",
"Z891K1": "Z40"
},
"K1": "Z41"
}
}
|
Erforderliche Arbeit
- Erheblicher Arbeitsaufwand zur besseren Unterstützung generischer Typen
- Identitätstyp hinzufügen
- Typen und alle Werte, die Identität nutzen, anpassen
- Erfordert eine Anpassung des Back-Ends für jeden Typ, der Identität verwendet, da sich die Instanzen geändert haben
Vorteile
- Keine Änderungen am Typ Z4/Typ
- Wir hätten sofort eine nette, einsatzbereite Oberfläche zum Erstellen von Instanzen, die eine Identität haben, und der Objektselektor könnte auf den richtigen Typ eingrenzen.
- Dies erfordert jedoch eine erhebliche Erweiterung der Unterstützung generischer Typen
Nachteile
- Generische Typen werden nicht gut unterstützt und stellen einen großen Aufwand dar. Wir müssten die Unterstützung für generische Typen erheblich verbessern, um tatsächlich die hier beschriebenen Vorteile zu erzielen.
- Wir müssten alle vorhandenen Werte mit einer Identität und alle Typen, die eine Identität verwenden, ändern. Aber besser jetzt als später.
- Prüfer müssen an den neuen generischen Typ angepasst werden. Die Arbeit muss mit der Umstellung der einzelnen Typen synchronisiert werden.
Vorschlag 3: Ein boolescher Schlüssel
Anstatt einen neuen Typ einzuführen, erweitern wir Z3/Schlüssel um einen weiteren Schlüssel, der boolesch ist und angibt, ob dieser Schlüssel ein Identitätsschlüssel ist.
Definition boolescher Werte
Unterschiede sind markiert.
{
"Type": "Type",
"Identity": "Boolean",
"Keys": ["Key",
{
"Type": "Key",
"Key type": "Identity",
"Key ID": "Z40K1",
"Names": [ … ],
"Identity": "True"
}
],
"Validator": …
}
|
{
"Z1K1": "Z4",
"Z4K1": "Z40",
"Z4K2": ["Z3",
{
"Z1K1": "Z3",
"Z3K1": "Z91",
"Z3K2": "Z40K1",
"Z3K3": [ … ],
"Z3K4": "Z41"
}
],
"Z4K3": …
}
|
In diesem Fall würde sich der Wert für Z41/wahr überhaupt nicht ändern.
{
"Type": "Boolean",
"Identity": "True"
}
|
{
"Z1K1": "Z40",
"Z40K1": "Z41"
}
|
Erforderliche Arbeit
- Schlüssel Z3K4 zum Typ Z3 / Schlüssel hinzufügen
- Typen, die Identität nutzen, anpassen
- Um diesen Schlüssel in die Typobjekte aufzunehmen, sind kleine Änderungen am Back-End oder Front-End erforderlich.
Vorteile
- Keine Änderung an den Instanzen, die Identität verwenden
- Die sofort einsatzbereite Oberfläche zum Bearbeiten der Identität eines Typs wäre in Ordnung
Nachteile
- Wir müssten den Typ Z4/Typ ändern
- Das haben wir allerdings erst vor kurzem gemacht und es lief ziemlich reibungslos
- Der Identitätsschlüssel wäre in jedem Schlüssel, was für etwas, das per Definition höchstens einmal pro Typ vorkommt, etwas unübersichtlich sein könnte
Vorschlag 4: Eine Liste von Markierungen
Anstatt einen neuen Typ einzuführen, erweitern wir Z3/Schlüssel um einen weiteren Schlüssel, der eine Liste von Z33/Schlüsselmarkierungen annimmt. Z33/Schlüsselmarkierung ist ein neuer Aufzählungstyp, der vorerst einen Wert für Z34/Identität hat.
Definition boolescher Werte
Unterschiede sind markiert.
{
"Type": "Type",
"Identity": "Boolean",
"Keys": ["Key",
{
"Type": "Key",
"Key type": "Identity",
"Key ID": "Z40K1",
"Names": [ … ],
"Markers": [Key marker,
"Identity"
]
}
],
"Validator": …
}
|
{
"Z1K1": "Z4",
"Z4K1": "Z40",
"Z4K2": ["Z3",
{
"Z1K1": "Z3",
"Z3K1": "Z91",
"Z3K2": "Z40K1",
"Z3K3": [ … ],
"Z3K4": ["Z33",
"Z34"
]
}
],
"Z4K3": …
}
|
In diesem Fall würde sich der Wert für Z41/wahr überhaupt nicht ändern.
{
"Type": "Boolean",
"Identity": "True"
}
|
{
"Z1K1": "Z40",
"Z40K1": "Z41"
}
|
Erforderliche Arbeit
- Typ Schlüsselmarkierung hinzufügen
- Identitätswert für den Typ Schlüsselmarkierung hinzufügen
- Schlüssel Z3K4 zum Typ Z3 / Schlüssel hinzufügen
- Typen, die Identität nutzen, anpassen
- Wahrscheinlich keine spezifischen Änderungen am Back-End oder Front-End erforderlich
Vorteile
- Keine Änderung an den Instanzen, die Identität verwenden
- Die sofort einsatzbereite Oberfläche zum Bearbeiten der Identität eines Typs wäre ganz nett
- Leicht erweiterbar (siehe optional unten)
Nachteile
- Wir müssten den Typ Z4/Typ ändern
- Das haben wir allerdings erst vor kurzem gemacht und es lief ziemlich reibungslos
Optional: Optional
Optionalität entscheidet darüber, ob ein Schlüssel angegeben werden muss oder nicht. Wir hatten von Anfang an optionale Schlüssel (z. B. Z14K2, Z60K2), aber wir haben keine Möglichkeit, sie zu markieren.
Vorschlag 3 und 4 würden uns eine Erweiterung zur Darstellung optionaler Schlüssel ohne großen Aufwand ermöglichen, und das sollten wir wahrscheinlich auch tun, da wir ohnehin daran arbeiten.
Für Vorschlag 3 würden wir einen weiteren Schlüssel, Z3K5/optional, mit einem booleschen Typ hinzufügen. Wenn Z3K5 auf wahr gesetzt ist, ist dieser Schlüssel optional und muss bei einer Instanz dieses Typs nicht vorhanden sein.
Für Vorschlag 4 wäre dies sogar noch einfacher, da wir nur eine weitere Instanz von Z33/Schlüsselmarkierung erstellen müssten. Die Standard-Benutzererfahrung hierfür bliebe weniger chaotisch.
Eine Überlegung ist die Frage, welche anderen Markierungen es geben könnte. Ich habe mir alle Typen auf Beta angesehen (99 Typen!) und das hat mich zu ein paar weiteren möglichen Markierungen inspiriert, die beispielsweise beim Verfeinern der Benutzeroberfläche helfen könnten (z. B. eine Markierung zum Erstellen von Optionsfeldern, Anzeigen von Kontrollkästchen, etc.), vielleicht in Zukunft sogar die Veränderlichkeit kennzeichnen oder die Auswertungsreihenfolge angeben. Aber ich würde sagen, es war kein riesiger Platz für Markierungen.
In jedem Fall müsste die Prüfung angepasst werden, um dieses neue Feld zu berücksichtigen. Dies kann zu einem späteren Zeitpunkt geschehen, da wir die Erstellung von Typen weiterhin kontrollieren, müsste jedoch erfolgen, bevor wir Benutzern das Erstellen von Typen erlauben.
Außerhalb des Projektumfangs
Schließlich wäre es schön, unterschiedliche Benutzererfahrungen für die Auswahl von Entitäten mit unterschiedlichen Kardinalitäten zu haben. Für boolesche Werte haben wir beispielsweise Optionsfelder zwischen den beiden Auswahlmöglichkeiten. Für Typen mit einer geringen Anzahl von Instanzen könnten wir ein ausklappbares Menü haben. Für Typen mit einer großen Anzahl von Instanzen könnten wir den Entitätsselektor während der Eingabe/Suche verwenden. Das Entwerfen und Implementieren dieser Erfahrungen ist nicht Teil dieser ersten Arbeit.