16. Modularität und Abstraktion

23
G.Heyer Digitale Informationsverarbeitung 1 16. Modularität und Abstraktion von-Neumann-Rechner zunächst binär programmiert: Daraus wurde ein Oktal- oder Sedezimal-Code: Darin enthaltene Befehlscodes wurden durch Operator-Symbole vereinfacht: Anstelle der Speicheradressen traten symbolische Marken und Bezeichner: Die Formulierung von Ausdrücken im Programm wurde zugelassen: ARGUM = ARGUM + 1 Durch Abstraktion von Berechnungsvorschriften entstanden Funktionen und Prozeduren 0000 1010 0000 0000 0011 1100 1000 1010 0000 0011 0000 0000 0000 0000 0000 0001 0000 1011 0000 0000 0011 1100 1000 1010 0A00 3C8A 0300 0001 0B00 3C8A LDA 3C8A AAD 0001 SPA 3C8A MARK1 = LDA ARGUM ADD 1 SPA ARGUM

description

16. Modularität und Abstraktion. von-Neumann-Rechner zunächst binär programmiert: Daraus wurde ein Oktal- oder Sedezimal-Code: Darin enthaltene Befehlscodes wurden durch Operator-Symbole vereinfacht: Anstelle der Speicheradressen traten symbolische Marken und Bezeichner: - PowerPoint PPT Presentation

Transcript of 16. Modularität und Abstraktion

Page 1: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung1

16. Modularität und Abstraktion

von-Neumann-Rechner zunächst binär programmiert:

Daraus wurde ein Oktal- oder Sedezimal-Code:

Darin enthaltene Befehlscodes wurden durch Operator-Symbole vereinfacht:

Anstelle der Speicheradressen traten symbolische Marken und Bezeichner:

Die Formulierung von Ausdrücken im Programm wurde zugelassen: ARGUM = ARGUM + 1

Durch Abstraktion von Berechnungsvorschriften entstanden Funktionen und Prozeduren

0000 1010 0000 0000 0011 1100 1000 10100000 0011 0000 0000 0000 0000 0000 00010000 1011 0000 0000 0011 1100 1000 1010

0A00 3C8A0300 00010B00 3C8A

LDA 3C8AAAD 0001SPA 3C8A

MARK1 = LDA ARGUM ADD 1 SPA ARGUM

Page 2: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung2

Abstraktion in Modula-2

Dienst-Modul in zwei Teile gegliedert:• Schnittstelle („Definition Module“) und

• Implementierung („Implementation Module“). Verknüpfung von Modulen durch Importieren der Bezeichner aus SchnittstelleVorteile:

• Schnittstellenprüfung ohne Kenntnis der Implementierung • Neuimplementierung der in der Schnittstelle deklarierten

Prozeduren zieht keine Änderung des importierenden Moduls nach sich, auch keine Neuübersetzung.

• Bei den Prozeduren ist eine höhere Abstraktion erreicht, den ihre Realisierung ist unsichtbar.

• Die Bearbeitung und Übersetzung ist jeweils auf relativ kleine, überschaubare und leicht zu handhabende Einheiten begrenzt.

• aussagekräftige Bezeichner • ausführliche Kommentare in den Schnittstellen, die die Funktion

der Prozeduren beschreiben, auch für Fehler- und Sonderfälle.

Nachteil: Konsistenz schwerer zu erreichen. Daher sind besonders wichtig:

Page 3: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung3

Modularisierung von Modula-2-Programmen

• Die Verwendung von Objekten aus anderen Modulen in einer Schnittstelle erfordert deren Import. Deren Gültigkeit beschränkt sich allerdings auf die Schnittstelle selbst. Werden diese Objekte auch in der Implementierung benutzt, so müssen sie dort erneut importiert werden.

• Die erste Regel gilt nur für Importe aus anderen Modulen, nicht für Konstanten, Typen und Variablen, die in der zugehörigen Schnittstelle deklariert sind. Diese dürfen nicht in der Implementierung desselben Moduls erneut deklariert werden. Nur die Prozedurköpfe werden wiederholt.

• Ein zyklischer Import (Beispiel: die Schnittstelle eines Moduls M2 importiert aus Modul M1 und umgekehrt) zwischen Schnittstellen ist nicht möglich. Wohl erlaubt ist hingegen, daß die Implementierungen gegenseitig aus den Schnittstellen importieren.

• Import einzelner Objekte: FROM Modul1 IMPORT a,b,c; (* a,b und c muessen in der Schnittstelle von Modul1 deklariert sein *)Verwendung: ...; a := b + c; ....

• Import des ganzen Moduls: IMPORT Modul1;Verwendung einzelner Objekte: ...; Modul1.a := Modul1.b + Modul1.c; ...

Page 4: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung4

Modularisierung von Doppelkette

Schnittstelle:

DEFINITION MODULE EinfuegenUndLoeschen; (* Programm 1a *)

TYPE ZeigTyp = POINTER TO ZeigRec; ZeigRec = RECORD Key : CARDINAL; Prev, Next : ZeigTyp; END (* RECORD *);VAR Anker : ZeigTyp;

PROCEDURE Einfuegen (Nr: CARDINAL); (* fuegt neues Element Nr in die geordnete Liste ein. *)

PROCEDURE Loeschen (Nr: CARDINAL); (* loescht Element Nr in Liste (muss vorhanden sein) *)

END EinfuegenUndLoeschen.

Page 5: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung5

Implementierung

IMPLEMENTATION MODULE EinfuegenUndLoeschen;FROM Storage IMPORT (* PROC *) ALLOCATE, DEALLOCATE;

PROCEDURE Einfuegen (Nr: CARDINAL); (* fuegt neues Element in die geordnete Liste ein *) VAR Hilf1 : ZeigTyp; BEGIN (* Einfuegen *) Hilf1 := Anker^.Next; WHILE (Hilf1^.Key < Nr) AND (Hilf1 <> Anker) DO Hilf1 := Hilf1^.Next; (* Nachfolger des neuen Elem. ...*) END (* WHILE *); (* ... oder Kettenende suchen *) WITH Hilf1^ DO (* der Nachfolger des neuen Elementes *) ALLOCATE (Prev^.Next, SIZE (ZeigRec)); (* neues Element einfuegen *) WITH Prev^.Next^ DO Key:= Nr; Next:= Hilf1; Prev:= Hilf1^.Prev; END (* WITH *); (* neues Element definiert *) Prev := Prev^.Next; (* neuen Vorgaenger anhaengen *) END (* WITH *); END Einfuegen;

Page 6: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung6

PROCEDURE Loeschen (Nr: CARDINAL); (* loescht Element in Liste. Element mit Key = Nr muss vorhanden sein. *) VAR Hilf1 : ZeigTyp; BEGIN (* Loeschen *) Hilf1 := Anker^.Next; WHILE Hilf1^.Key # Nr DO Hilf1 := Hilf1^.Next; (* suchen *) END; WITH Hilf1^ DO Prev^.Next := Next; Next^.Prev := Prev; END (* WITH *); DEALLOCATE (Hilf1, SIZE (ZeigRec)); (* Element ist geloescht *) END Loeschen;

BEGIN (* EinfuegenUndLoeschen *)(* Kette mit fliegendem Anker initialisieren *) ALLOCATE (Anker, SIZE (ZeigRec)); WITH Anker^ DO Key := 0; Next := Anker; Prev := Anker; END (* WITH *);END EinfuegenUndLoeschen.

Page 7: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung7

Test-Modul

MODULE DoppelKette; (* Programm 1c *)FROM InOut IMPORT (* PROC *) WriteCard, WriteLn;FROM EinfuegenUndLoeschen IMPORT (* TYPE *) ZeigTyp, ZeigRec, (* VAR *) Anker, (* PROC *) Einfuegen, Loeschen;PROCEDURE ZeigKette;VAR Hilf1 : ZeigTyp; BEGIN (* ZeigKette *) Hilf1 := Anker^.Next; WHILE Hilf1 # Anker DO WriteCard (Hilf1^.Key, 3); Hilf1 := Hilf1^.Next; END (* WHILE *); WriteLn;END ZeigKette;

BEGIN (* DoppelKette *) Einfuegen(7); Einfuegen(1); Einfuegen(4); Einfuegen(5); Einfuegen(9); ZeigKette; Loeschen (1); Loeschen (9); Loeschen (5); ZeigKette; END DoppelKette.

Page 8: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung8

Datenkapselung

Bei vollständiger Datenkapselung darf keine Variable exportiert werden

Schnittstelle

Implementierung

Konstanten- undTypdefinitionenProzedurdeklarationen

VAR gekapselte DatenstrukturProzedurdefinitioneninterne Daten und ProzedurenBEGIN Initialisierung END

Kunden-Modul

Anbindung anDienstmodul durchProzeduraufrufe

Dienst-Modul

Import

Page 9: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung9

Schnittstelle

DEFINITION MODULE KettenKapsel; (* Programm 2a *)(* Besser strukturierte Variante des Programms 1 *)

PROCEDURE Einfuegen (Nr: CARDINAL); (* fuegt neues Element in die geordnete Liste ein. *) PROCEDURE Loeschen (Nr: CARDINAL); (* loescht Elem. in Liste. Element mit Key = Nr muss vorhanden sein *) PROCEDURE ZeigKette; (* zeigt den aktuellen Stand der Kette auf dem Bildschirm *) END KettenKapsel.

Page 10: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung10

ImplementierungIMPLEMENTATION MODULE KettenKapsel; (* Programm 2b *)

FROM Storage IMPORT (* PROC *) ALLOCATE, DEALLOCATE;FROM InOut IMPORT (* PROC *) WriteCard, WriteLn;TYPE ZeigTyp = POINTER TO ZeigRec;TYPE ZeigRec = RECORD Key : CARDINAL; Prev, Next : ZeigTyp; END (* RECORD *);VAR Anker : ZeigTyp;

PROCEDURE Einfuegen (Nr: CARDINAL); ... wie oben in Programm 1b ... END Einfuegen; PROCEDURE Loeschen (Nr: CARDINAL); ... wie oben in Programm 1b ... END Loeschen; PROCEDURE ZeigKette; ... wie oben in Programm 1c ... END ZeigKette;BEGIN (* KettenKapsel *) ... Initialisierung wie oben in Programm 1b ...END KettenKapsel.

Page 11: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung11

Test-Modul

MODULE DoppelKette; (* Programm 2c *)(* Version mit Kapselung der Daten *)FROM KettenKapsel IMPORT (* PROC *) Einfuegen, Loeschen, ZeigKette;BEGIN (* DoppelKette *) ... Hauptprogramm wie in Programm 1c ...END DoppelKette.

ZeigTyp, ZeigRec und Anker sind private Informationen der Implementierung. Sie sind anderen Modulen nicht bekannt

Vorteile: Datenstrukturen vor Fehlinterpretationen geschützt, Mißbrauch ist erschwert, gekapselte Datenstruktur kann ohne Auswirkung auf andere Module geändert werden

Das Prinzip der Datenkapselung wurde 1972 von David Parnas unter der Bezeichnung information hiding eingeführt.

Page 12: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung12

Beispiel Warteschlange

DEFINITION MODULE SchlKapsel; (* Programm 4a *)(* Demonstr. Kapselung: FIFO-Speicher fuer CARDINAL-Zahlen *)

PROCEDURE Bringen (Eintrag : CARDINAL); (* wenn istVoll vorher TRUE war, keine Wirkung; sonst wird Eintrag der Schlange zugefuegt *) PROCEDURE Holen (VAR Eintrag : CARDINAL); (* wenn istLeer vorher TRUE war, keine Wirkung; sonst wird Par. Eintrag mit dem aeltesten Eintrag der Schlange besetzt, und dieser wird aus der Schlange entfernt *) PROCEDURE istLeer (): BOOLEAN; (* TRUE, genau wenn Schlange kein Element enthaelt *) PROCEDURE istVoll (): BOOLEAN; (* TRUE, genau wenn Schlange kein Element mehr aufnehmen kann *) END Schlkapsel.

Page 13: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung13

ImplementierungIMPLEMENTATION MODULE SchlKapsel; (* Programm 4b *)

(* Demonstr. der Kapselung: FIFO-Speicher fuer CARDINAL-Zahlen Version mit Ringpuffer *)CONST MaxElemente = 100; Feldlaenge = MaxElemente+1; (* Minim. 1 Platz bleibt frei *)TYPE SchlIndTyp = [0 .. Feldlaenge-1];VAR Schlange : ARRAY SchlIndTyp OF CARDINAL; (* die gekapselte *) AnfangVoll, AnfangLeer: SchlIndTyp; (* Datenstruktur *)

PROCEDURE Nachfolger (Arg: SchlIndTyp) : SchlIndTyp; (* intern ,zyklische Nachfolgefunktion *) BEGIN (* Nachfolger *) RETURN (Arg + 1) MOD Feldlaenge END Nachfolger; PROCEDURE Bringen (Eintrag : CARDINAL); BEGIN (* Bringen *) IF NOT istVoll () THEN Schlange [AnfangLeer] := Eintrag; AnfangLeer := Nachfolger (AnfangLeer); END (* IF *); END Bringen;

Page 14: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung14

Implementierung, Fortsetzung

PROCEDURE Holen (VAR Eintrag : CARDINAL); BEGIN (* Holen *) IF NOT istLeer () THEN Eintrag := Schlange [AnfangVoll]; AnfangVoll := Nachfolger (AnfangVoll); END (* IF *); END Holen; PROCEDURE istLeer () : BOOLEAN; BEGIN (* istLeer *) RETURN AnfangVoll = AnfangLeer END istLeer;

PROCEDURE istVoll () : BOOLEAN; BEGIN (* istVoll *) RETURN Nachfolger (AnfangLeer) = AnfangVoll END istVoll;

BEGIN (* Initialisierung *) AnfangVoll := 0; AnfangLeer := 0;END SchlKapsel.

Page 15: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung15

Testmodul

MODULE KapselTest; (* Programm 4c *)FROM SchlKapsel IMPORT (* PROC *) Bringen, Holen, istLeer, istVoll;FROM InOut IMPORT (* PROC *) ReadCard, Write, WriteLn, WriteCard, WriteString;

PROCEDURE WriteB (Value: BOOLEAN); (* Ausgabe von Wahrheitswerten *) BEGIN (* WriteB *) IF Value THEN Write ('T'); ELSE Write ('F'); END; END WriteB;

VAR Wert : CARDINAL;

BEGIN (* KapselTest *) WriteString ('*** Start Test-Programm f. SchlKapsel ***'); WriteLn; WriteLn; WriteString ('Gib Zahl ohne Vorzeichen,'); WriteString (' 0 fuer Ausgabe, 999 fuer Ende'); WriteLn; WriteLn;

Page 16: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung16

Testmodul, Fortsetzung LOOP (* jeweils Ein- oder Ausgabe eines Wertes *)

Write ('>'); ReadCard (Wert); Write (' '); IF Wert = 999 THEN EXIT (* Abbruchbedingung *) ELSIF Wert = 0 THEN (* Wert aus Schlange holen *) IF istLeer () THEN WriteString (' Schlange ist leer'); ELSE Holen (Wert); WriteCard (Wert, 4); WriteString (' istLeer = '); WriteB (istLeer ()); END (* IF istLeer () *); ELSE (* Wert in Schlange setzen *) IF istVoll () THEN WriteString (' Schlange ist voll'); ELSE Bringen (Wert); WriteString (' istVoll = '); WriteB (istVoll ()); END (* IF istVoll () *); END (* IF *); WriteLn; END (* LOOP *); WriteString ('*** Ende Test ***'); WriteLn;END KapselTest.

Page 17: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung17

Abstrakte Datentypen (ADT)Ein Datentyp ist ein Schema, aus dem Variablen gebildet werden können. Ein Abstrakter Datentyp ist ein Schema zur Bildung geschützter Variablen im

Sinne der Kapselung. Er besteht aus • dem Namen des Typs, dessen innere Struktur nicht sichtbar ist, und • der Menge der zulässigen Operationen auf Objekten dieses Typs. Ein ADT ist nicht ein einzelnes Objekt, sondern ein Typ, von dem es beliebig

viele Variablen geben kann. Die Initialisierung erfolgt jeweils einzeln.

Schnittstelle

Implementierung

TYPE pT; (* privater Typ *)Prozedurdeklarationen(auch Initialisierungsprozedur)

TYPE pT = ...;Prozedurdefinitioneninterne Daten und Prozeduren(* keine Initialisierung *) END

Kunden-Modul

Anbindung anDienstmodul durchProzeduraufrufe

Import:privater TypProzeduren

Page 18: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung18

Charakteristika von ADTs

• Der Typ, auf den sich die Operationen des ADT beziehen, wird in der Schnittstelle deklariert, nicht aber definiert. Es handelt sich hierbei um einen opaken oder privaten Typ.

• Die Kunden-Module importieren den opaken Typ samt den Prozeduren und legen Variablen an.

• Die Initialisierung der Variablen bedarf einer eigenen Prozedur.• Alle Operationen müssen durch das Modul ausgeführt werden, das den ADT

exportiert. Die betreffenden Variablen werden als Parameter übergeben.Vorteile:• Durch die Kapselung der Datenstrukturen sind Fehlinterpretationen

vermindert und ist Mißbrauch erschwert.• Die Datenstruktur ist ohne Auswirkungen auf andere Module änderbar.• Die Zahl der Variablen, die aus einem ADT gebildet werden, bleibt offen.Nachteile:• Die Datenzugriffe sind im allgemeinen etwas weniger effizient.

Page 19: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung19

ADT Stack für CARDINAL

Ein Stack (Keller) ist eine variable Datenstruktur zur Verwaltung von Elementen des gleichen Typs nach dem LIFO-Prinzip (last in first out).

Anschaulich: lineare Liste, bei der Einfügen, Löschen und Abfrage nur an einem Ende ausgeführt werden.

Definierte Operationen:• Push (Element): Einfügen eines neuen (dann obersten) Elementes,• Pop(): Entfernen des obersten Elementes,• Top(): Abfrage des obersten Elementes,• Empty(): Abfrage, ob der Stack leer ist.

Page 20: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung20

Schnittstelle

DEFINITION MODULE ADTStack; (* Programm 6a *)(* Demonstration eines ADTs: LIFO-Speicher fuer CARDINAL-Zahlen *)TYPE StackTyp; (* ein privater (opaker) Typ *) PROCEDURE Push (VAR Stack : StackTyp; Eintrag : CARDINAL); (* Speichern des uebergebenen Wertes als oberstes Stackelement *) PROCEDURE Pop ( VAR Stack : StackTyp; VAR istLeer : BOOLEAN ) : CARDINAL; (* Abfrage und Entfernen des obersten Stackelementes: wenn istLeer FALSE, wird Wert des obersten Stackelements geliefert und Element geloescht; sonst keine Wirkung und Wert ist 0. *) PROCEDURE Top ( VAR Stack : StackTyp; VAR istLeer : BOOLEAN ) : CARDINAL; (* Abfrage des obersten Stackelementes:wenn istLeer FALSE, wird Wert des obersten Stackelementes geliefert, sonst 0. *) PROCEDURE Empty (Stack : StackTyp): BOOLEAN; (* TRUE, genau wenn der Stack leer ist *) PROCEDURE Initial (VAR Stack : StackTyp); (* Initialisierung des Stacks *) PROCEDURE Delete (VAR Stack : StackTyp); (* Loeschen des Stacks, d.h. Loeschen aller Elemente *) END ADTStack.

Page 21: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung21

Implementierung

IMPLEMENTATION MODULE ADTStack; (* Programm 6b *)(* Demonstration eines ADTs: LIFO-Speicher fuer CARDINAL-Zahlen *)FROM Storage IMPORT (* PROC *) ALLOCATE, DEALLOCATE;TYPE StackTyp = POINTER TO ElementTyp; ElementTyp = RECORD Wert : CARDINAL; Nachfolger : StackTyp; END (* RECORD *);

PROCEDURE Push (VAR Stack : StackTyp; Eintrag : CARDINAL); VAR NeuElement : StackTyp; BEGIN (* Push *) (* Neuen Eintrag als 1. Element einfuegen *) ALLOCATE (NeuElement, SIZE (ElementTyp)); WITH NeuElement^ DO Wert := Eintrag; Nachfolger := Stack; END (* WITH *); Stack := NeuElement; END Push;

Page 22: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung22

PROCEDURE Pop (VAR Stack : StackTyp; VAR istLeer : BOOLEAN ) : CARDINAL; VAR Eintrag : CARDINAL; Hilf : StackTyp; BEGIN (* Pop *) (* Erstes Element lesen und loeschen *) istLeer := Empty(Stack); IF istLeer THEN Eintrag := 0; ELSE Eintrag := Stack^.Wert; Hilf := Stack; Stack := Stack^.Nachfolger; DEALLOCATE (Hilf, SIZE (ElementTyp)); END; RETURN Eintrag END Pop;

PROCEDURE Top (VAR Stack : StackTyp; VAR istLeer : BOOLEAN ) : CARDINAL; VAR Eintrag : CARDINAL; BEGIN (* Top *) (* Erstes Element lesen *) istLeer := Empty(Stack); IF istLeer THEN Eintrag := 0; ELSE Eintrag := Stack^.Wert; END; RETURN Eintrag END Top;

Page 23: 16. Modularität und Abstraktion

G.Heyer Digitale Informationsverarbeitung23

Implementierung, 3

PROCEDURE Empty (Stack : StackTyp): BOOLEAN; BEGIN (* Empty *) RETURN (Stack = NIL) END Empty; PROCEDURE Initial (VAR Stack : StackTyp); BEGIN (* Initial *) Stack := NIL; END Initial;

PROCEDURE Delete (VAR Stack : StackTyp); VAR Hilf : StackTyp; BEGIN (* Delete *) WHILE Stack # NIL DO Hilf := Stack; Stack := Stack^.Nachfolger; DEALLOCATE (Hilf, SIZE (ElementTyp)); END (* WHILE *); END Delete;

END ADTStack.