next up previous
Nächste Seite: Zusammenfassung Aufwärts: OO-Techniken in Oberon Vorherige Seite: Operationen ohne zentrale Auftragnehmer


Disziplinen

Das Modul Disciplines ermöglicht es, an Erweiterungen von Disciplines.Object beliebige weitere Datenstrukturen, die Erweiterungen von Disciplines.Discipline sind, anzuhängen und wiederzufinden:

DEFINITION Disciplines;

   IMPORT Objects;

   TYPE
      Identifier = LONGINT;

      Discipline = POINTER TO DisciplineRec;
      DisciplineRec =
         RECORD
            (Objects.ObjectRec)
            id: Identifier;
         END;

      Object = POINTER TO ObjectRec;
      ObjectRec =
         RECORD
            (Objects.ObjectRec)
         END;

   PROCEDURE Unique() : Identifier;
   PROCEDURE Add(object: Object; discipline: Discipline);
   PROCEDURE Remove(object: Object; id: Identifier);
   PROCEDURE Seek(object: Object; id: Identifier;
                  VAR discipline: Discipline) : BOOLEAN;

END Disciplines.

Für jeden Typ, der von Disciplines.Discipline abgeleitet wird, sollte zum Zeitpunkt der Initialisierung des zugehörigen Moduls eine eindeutige Zahl mit Hilfe von Disciplines.Unique bestimmt werden. Später wird dann bei dem Anlegen der entsprechenden Datenstruktur die Komponente id damit belegt. Nachdem die Datenstruktur mit Add an das Objekt angeheftet worden ist, kann sie später durch Angabe dieser Zahl mit Seek wiedergefunden oder mit Remove entfernt werden.

Als Beispiel für die Verwendung der Disziplinen eignet sich das Problem der nachträglich mit Farben zu versehenden Figuren, das als schwer zu lösendes Problem im Bereich der objekt-orientierten Sprachen gilt. Bei herkömmlichen Techniken bleibt tatsächlich nur die Erweiterung der Basisklasse um die entsprechende Farbkomponente oder die Definition einer weiteren Hierachie übrig, bei der sich zu jeder Erweiterung eine Farbvariante gesellt. Mit Hilfe der Disziplinen ist es jedoch möglich, an jede Erweiterung von Figure eine Farbinformation anzuheften:2.2

DEFINITION Colours;

   IMPORT Figures;

   TYPE
      Colour = INTEGER;

   PROCEDURE SetColour(figure: Figures.Figure; colour: Colour);
   PROCEDURE GetColour(figure: Figures.Figure; VAR colour: Colour);

END Colours.

MODULE Colours;

   IMPORT Disciplines, Figures;

   CONST
      defaultColour = 0;

   TYPE
      Colour = INTEGER;

      ColourDiscipline = POINTER TO ColourDisciplineRec;
      ColourDisciplineRec =
         RECORD
            (Disciplines.DisciplineRec)
            colour: Colour;
         END;
   VAR
      colourDiscId: Disciplines.Identifier;

   PROCEDURE SetColour(figure: Figures.Figure; colour: Colour);
      VAR
         colourDisc: ColourDiscipline;
   BEGIN
      IF Disciplines.Seek(figure, colourDiscId, colourDisc) THEN
         colourDisc.colour := colour;
      ELSE
         NEW(colourDisc); colourDisc.id := colourDiscId;
         colourDisc.colour := colour;
         Disciplines.Add(figure, colourDisc);
      END;
   END SetColour;

   PROCEDURE GetColour(figure: Figures.Figure; VAR colour: Colour);
      VAR
         colourDisc: ColourDiscipline;
   BEGIN
      IF Disciplines.Seek(figure, colourDiscId, colourDisc) THEN
         colour := colourDisc.colour;
      ELSE
         colour := defaultColour;
      END;
   END GetColour;

BEGIN
   colourDiscId := Disciplines.Unique();
END Colours.

Natürlich ist es auch möglich, Auftragnehmer oder Schnittstellenrecords mit Hilfe von Disciplines an ein Objekt anzuhängen. Allerdings werden in dieser Form weder nicht überdefinierbare Operationen (wie die Operationen von Colours) noch ggf. die Operationen, die auf Basis von weiteren Schnittstellenrecords oder Auftragnehmern definiert sind, von Delegationen erfaßt.

Es hilft jedoch nicht, die Operationen auf Basis von Aufträgen durchzuführen, die über die Operation Send der Basisabstraktion verschickt werden. Hierbei landet der Auftrag bei der Implementierung, die von den Disziplinen und deren Operationen nichts weiß. Eine Lösung für dieses Problem wird von dem Modul Messages der Ulmer Oberon-Bibliothek angeboten. Hierbei werden Aufträge an alle Interessenten weitergegeben, so daß auch Module, die nur über Disziplinen an einem Objekt beteiligt sind, ihre Aufträge über einen delegierbaren Zugang erhalten. Da die Aufträge von Messages persistent sind, d.h. in eine Sequenz von Bytes und wieder zurück verwandelt werden können, sind damit Aufrufe über die Grenzen eines Programms hin delegierbar (remote procedure calls). Bemerkenswert ist hier, daß weder der Aufrufer noch die Prozedur, die den Auftrag zusammenstellt, davon etwas bemerken.


next up previous
Nächste Seite: Zusammenfassung Aufwärts: OO-Techniken in Oberon Vorherige Seite: Operationen ohne zentrale Auftragnehmer
Andreas Borchert 2000-12-18