Opaker Datentyp
Einführung
Ein opaker Datentyp (engl. *opaque data type*) ist ein Datentyp, dessen interne Struktur für den Benutzer **verborgen** ist. Benutzer können auf den Typ nur über definierte Schnittstellen oder Funktionen zugreifen, nicht direkt auf die internen Daten.
Opake Datentypen werden verwendet, um **Kapselung**, **Modularität** und **Sicherheit** in Software und verteilten Systemen zu gewährleisten.
Eigenschaften
- Verborgene Implementierung – die interne Darstellung ist nicht sichtbar.
- Zugriff nur über definierte Operationen – z. B. Erstellen, Ändern, Löschen.
- Flexibilität – die Implementierung kann geändert werden, ohne den Benutzercode zu beeinflussen.
- Unterstützt API-Design und Datensicherheit.
Beispiel in C
// header.h
typedef struct MyStruct MyStruct; // opaker Datentyp
MyStruct* create();
void set_value(MyStruct* s, int v);
int get_value(MyStruct* s);
void destroy(MyStruct* s);
// implementation.c
struct MyStruct {
int value;
};
MyStruct* create() { return malloc(sizeof(MyStruct)); }
void set_value(MyStruct* s, int v) { s->value = v; }
int get_value(MyStruct* s) { return s->value; }
void destroy(MyStruct* s) { free(s); }
Opake Datentypen in RPC
In Remote Procedure Call (RPC)-Systemen werden opake Datentypen verwendet, um **undurchsichtige Datenstrukturen** zwischen Client und Server zu übertragen.
Beispiel in ONC RPC IDL:
program OPAQUE_PROG {
version OPAQUE_VERS {
opaque data<>; // Opaker Datentyp beliebiger Länge
} = 1;
} = 0x20000002;
- Der Stub übernimmt das Marshalling und Unmarshalling.
- Client und Server kennen nur die Schnittstelle, nicht die interne Struktur.
Opake Datentypen in XDR
In External Data Representation (XDR), das in RPC verwendet wird, werden opake Datentypen genutzt, um **flexible Binärdaten** zu serialisieren.
Beispiel:
typedef opaque myblob<1024>; // Binärdaten bis 1024 Byte
- `myblob` kann beliebige Daten enthalten.
- Sender und Empfänger verwenden Marshalling/Unmarshalling.
- Die interne Struktur bleibt für beide Seiten undurchsichtig.
Vorteile
- Kapselung und Schutz der internen Datenstruktur
- Flexibilität bei Implementierungsänderungen
- Reduzierte Abhängigkeit zwischen Modulen oder Systemen
- Einheitliche Schnittstelle für verschiedene Implementierungen
Nachteile
- Kein direkter Zugriff auf interne Daten
- Jede Operation benötigt definierte Funktionen
- Debugging kann schwieriger sein, da interne Struktur verborgen bleibt