Spezifikation von Daten- und Programmstrukturen
Dieser Beitrag ist eine Begriffserklärung zur Spezifikation von Daten- und Programmstrukturen – inklusive Prüfungsfragen, Kernkomponenten und Tags.
In a Nutshell
Datenstrukturen werden formal über Modelle, Typen, Invarianten und Schemata beschrieben. Programmstrukturen werden über Schnittstellen, Vor-/Nachbedingungen, Zustände und Kontrollfluss präzisiert. Ziel ist eindeutige, testbare und wartbare Software.
Kompakte Fachbeschreibung
Datenspezifikation
- Modelle: ER-Modell oder UML-Klassendiagramm
- Kardinalitäten, Schlüssel, Normalisierung (bis 3NF)
- Regeln als Invarianten
- Schnittstellendaten maschinenlesbar: JSON Schema (oder DDL/XML Schema)
Programmspezifikation
- Module/APIs mit Signaturen
- Fehlerverträge
- Design by Contract: Vorbedingung, Nachbedingung, Invariante
- Verhalten: Zustandsautomaten, Aktivitäts-/Sequenzdiagramme
- Präzisierung: OCL (Object Constraint Language)
Spezifikationen dienen als Basis für automatische Validierung, Stub-Generierung und Contract Tests.
Prüfungsrelevante Stichpunkte
- Kardinalitäten/Schlüssel korrekt: Datenmodelle müssen eindeutige Schlüssel und korrekte Beziehungen zwischen Entitäten definieren. Falsch gesetzte Kardinalitäten führen zu inkonsistenten Daten oder fehlerhaften Abfragen.
- JSON Schema zur Eingabevalidierung: JSON Schema beschreibt erlaubte Strukturen und Wertebereiche für JSON-Daten. Damit kannst Du Eingaben bereits vor der Verarbeitung maschinell prüfen und fehlerhafte Daten ablehnen.
- Vor-/Nachbedingungen und Fehlerfälle: Design by Contract formuliert Verpflichtungen für Aufrufer und Aufgerufene. Vorbedingungen müssen vor dem Aufruf gelten, Nachbedingungen danach. Fehlerfälle werden explizit als Ausnahmen definiert.
- Zustandsmodelle für erlaubte Übergänge: Zustandsdiagramme zeigen, in welchen Zuständen sich ein Objekt befinden darf und welche Übergänge erlaubt sind. Das verhindert ungültige Zustandsänderungen, zum Beispiel eine stornierte Bestellung, die erneut versendet wird.
- Testfälle ableiten (Äquivalenzklassen/Grenzwerte): Aus Spezifikationen lassen sich gezielt Testfälle entwickeln. Invarianten und Bedingungen ergeben Äquivalenzklassen, Schlüssel und Grenzwerte ergeben konkrete Testdaten.
- Versionierung, Migration und Deprecation: Schemata und Schnittstellen ändern sich im Laufe der Zeit. Semantische Versionierung, Deprecation-Hinweise und Migrationspfade helfen, Änderungen kontrolliert einzuführen.
- Security: Validierung, Rechte und Auditfelder: Spezifikationen müssen sicherheitsrelevante Aspekte enthalten. Dazu gehören Eingabevalidierung, Zugriffsrechte und Protokollierung, wer wann welche Daten geändert hat.
Kernkomponenten
- Abstrakter Datentyp + Wertebereich – Ein abstrakter Datentyp definiert die möglichen Werte und Operationen einer Datenstruktur. Der Wertebereich legt fest, welche Eingaben gültig sind, zum Beispiel positive Zahlen oder Zeichenketten mit bestimmten Mustern.
- Strukturmodell (ER/Klasse) – Ein ER-Modell oder UML-Klassendiagramm beschreibt die Entitäten, ihre Attribute und Beziehungen. Das Strukturmodell ist die Grundlage für Datenbanken und Objektmodelle.
- Kardinalitäten + Normalformen – Kardinalitäten geben an, wie viele Entitäten miteinander verbunden sind. Normalformen reduzieren Redundanzen und verhindern Anomalien bei Einfügen, Ändern und Löschen.
- Datenschema (JSON Schema) – JSON Schema ist eine maschinenlesbare Beschreibung von JSON-Daten. Es legt Typen, Pflichtfelder, Wertebereiche und Muster fest und ermöglicht automatische Validierung.
- API-Vertrag + Fehlercodes – Ein API-Vertrag beschreibt Schnittstellen, Parameter, Rückgabewerte und Fehlerfälle. Fehlercodes und Nachrichten helfen Aufrufern, Probleme zu erkennen und richtig zu behandeln.
- Design by Contract – Design by Contract definiert Vorbedingungen, Nachbedingungen und Invarianten. Es stellt sicher, dass Aufrufer und Aufgerufene ihre Vereinbarungen einhalten, und erleichtert die Fehlersuche.
- Zustands-/Prozessmodelle – Zustandsmodelle zeigen erlaubte Zustände und Übergänge. Prozessmodelle wie Aktivitätsdiagramme beschreiben Abläufe und Entscheidungen innerhalb der Programmlogik.
- Qualitätsregeln (NFA) – Nicht-funktionale Anforderungen wie Performance, Sicherheit oder Verfügbarkeit werden als Qualitätsregeln festgelegt. Sie ergänzen die funktionale Spezifikation um messbare Kriterien.
- Testableitung (Contract/Property) – Aus Spezifikationen lassen sich Testfälle ableiten. Contract Tests prüfen Schnittstellenverträge, Property-based Tests prüfen allgemeine Eigenschaften wie Invarianten.
- Versions-/Migrationskonzept – Änderungen an Schemata oder APIs müssen versioniert werden. Ein Migrationskonzept beschreibt, wie bestehende Daten und Clients auf neue Versionen umgestellt werden.
Praxisbeispiel (Bestellung)
JSON Schema (Auszug als Text)
type: object
required: id, kundeId, positionen, gesamt
properties:
id: string (pattern ^ORD-[0-9]{6}$)
gesamt: number (minimum 0)
positionen: array (minItems 1)
OCL-Invarianten (sinngemäß)
context Bestellung inv SummeStimmt:
gesamt = sum(positionen.preis * positionen.menge)
context Bestellung inv PositiveMengen:
forAll(positionen, menge > 0)
Service-Vertrag (Pseudocode)
interface BestellService
legeBestellungAn(warenkorb)
vorbedingung:
warenkorb.positionen nicht leer und warenkorb.gesamt > 0
nachbedingung:
result.status = ANGELEGT und result.gesamt = warenkorb.gesamt
fehlerfälle:
UngültigeDaten, ZahlungAbgelehnt
Vorteile und Nachteile
Vorteile
- Eindeutige Kommunikation
- Automatisierbare Validierung
- Bessere Testbarkeit und weniger Integrationsfehler
Nachteile
- Initialaufwand
- Pflege von Versionen/Migrationen
- Risiko der Überformalisierung
Typische Prüfungsfragen (mit Kurzantwort)
- ER-Modell vs Klassendiagramm? ER für Daten/Persistenz, Klasse für Typen + Operationen.
- Wozu Invarianten? Regeln, die immer gelten müssen.
- Wie entstehen Tests aus Spezifikation? Vorbedingungen/Invarianten → Äquivalenzklassen/Grenzwerte.
- Wie versioniert man Schemata sicher? Semver, Breaking Changes = Major, Deprecation + Migration.
Lernstrategie
- Verständniseinstieg: Modelliere eine kleine Domäne wie eine Bibliothek oder einen Online-Shop als Klassendiagramm. Leite daraus ein JSON Schema und einige Invarianten ab.
- Vertiefungsmethode: Formuliere für eine bestehende Funktion Vorbedingungen, Nachbedingungen und Fehlerfälle. Schreibe daraus Testfälle mit Äquivalenzklassen und Grenzwerten.
- Prüfungsfokustraining: Übe die Unterscheidung zwischen ER-Modell und Klassendiagramm sowie die korrekte Notation von Invarianten und Zustandsübergängen.
- Fehlervermeidung: Halte Spezifikationen aktuell. Wenn sich das System ändert, müssen auch Modell, Schema und Verträge angepasst werden, sonst entsteht technische Schuld.
Übungsbeispiel 1: JSON Schema für eine Bestellung
Eine Bestellung hat eine ID im Format ORD- plus sechs Ziffern, eine Kunden-ID, mindestens eine Position und einen Gesamtbetrag, der größer oder gleich null sein muss. Das JSON Schema legt diese Regeln formal fest und kann die Eingabe automatisch prüfen.
Übungsbeispiel 2: OCL-Invarianten für eine Bestellung
Eine Bestellung hat die Invariante, dass der Gesamtbetrag der Summe aller Positionen entsprechen muss. Eine weitere Invariante besagt, dass jede Menge positiv sein muss. Solche Invarianten lassen sich in Tests überführen.
Übungsbeispiel 3: Design by Contract für einen Bestellservice
Die Funktion legeBestellungAn verlangt als Vorbedingung einen nicht leeren Warenkorb mit positivem Gesamtbetrag. Als Nachbedingung gilt, dass die Bestellung den Status ANGELEGT hat und der Gesamtbetrag stimmt. Fehlerfälle wie ungültige Daten oder abgelehnte Zahlung werden explizit benannt.
Übungsaufgabe 1: Modelltyp wählen
Du möchtest die Datenstruktur für eine relationale Datenbank dokumentieren. Welches Modell ist passender, ER-Modell oder Klassendiagramm?
Lösung: Das ER-Modell ist passender, weil es Entitäten, Attribute und Beziehungen für den Datenbankentwurf darstellt. Ein Klassendiagramm fokussiert stärker auf Typen, Operationen und Vererbung.
Übungsaufgabe 2: Invariante ableiten
Eine Bestellposition hat die Attribute preis und menge. Formuliere eine sinnvolle Invariante.
Lösung: Eine sinnvolle Invariante ist menge > 0 und preis >= 0. Beide müssen immer gelten, damit die Position gültig ist.
Übungsaufgabe 3: Zustandsmodell erklären
Eine Bestellung kann die Zustände ANGELEGT, BEZAHLT, VERSENDET und STORNIERT haben. Welche Übergänge sind sinnvoll, welche nicht?
Lösung: Sinnvoll sind ANGELEGT → BEZAHLT, BEZAHLT → VERSENDET und ANGELEGT → STORNIERT. Unsinnig wäre VERSENDET → ANGELEGT oder STORNIERT → VERSENDET, weil diese Übergänge den Geschäftsablauf verletzen.
Themenanalyse
- Technischer Kern: Formale Beschreibung von Daten und Verhalten. Spezifikationen legen fest, welche Daten erlaubt sind und wie sich das System verhalten muss. Modelle, Schemata und Verträge sind die zentralen Instrumente.
- Implementierungsherausforderungen: Balance zwischen Präzision und Praktikabilität. Zu formale Spezifikationen sind aufwändig zu pflegen, zu unpräzise führen zu Missverständnissen. Der passende Detailgrad hängt vom Projekt ab.
- Sicherheitsimplikationen: Validierung und Rechte als Teil der Spezifikation. Eingabevalidierung, Zugriffskontrolle und Auditpfade müssen bereits in der Spezifikation berücksichtigt werden, damit sie in der Implementierung nicht vergessen werden.
- Dokumentationspflichten: Modelle, Schemata und Verträge als Projektdokumentation. Spezifikationen sind verbindliche Bestandteile der Projektdokumentation. Sie helfen, Anforderungen zwischen Fachbereich, Entwicklung und Testing abzustimmen.
- Wirtschaftliche Bewertung: Aufwand für Spezifikation vs. Einsparung durch weniger Fehler. Eine gute Spezifikation kostet Zeit am Anfang, vermeidet aber teure Fehler und Nachbesserungen in späteren Phasen. Automatisierbare Validierung und Testableitung erhöhen den Nutzen.