StructorizerHandbuch DE

Auslagern (Outsourcing)

📷 Auslagern von Elementen in ein Unterprogramm

Seit Version 3.27 können Sie eine zusammenhängende Teilfolge von Elementen Ihres Diagramms auswählen und sie blitzschnell automatisch in ein neues Unterprogramm auslagern.

Stellen Sie sich folgendes Beispiel einer statistischen Berechnung vor: Es beginnt mit der manuellen Eingabe einiger numerischer Werte, berechnet dann deren Durchschnitt und leitet schließlich die Standardabweichung ab. Sie möchten diesen Algorithmus aufteilen. Beginnen wir mit der Standardabweichung. Wählen Sie alle an diesem Teil der Berechnung beteiligten Elemente aus:

Auslagerungs-Demo: das urspruengliche Programm
Auslagerungs-Demo: das urspruengliche Programm

Um den ausgewählten Teil in ein Unterprogramm umzuwandeln, können Sie:

  • den Menüeintrag "Diagram › Outsource" (Diagramm › Auslagern) wählen,
  • den Kontextmenüeintrag "Outsource" (Auslagern) wählen oder
  • die Tastenkombination <Ctrl><F11> drücken.
Auslagerungs-Demo: Menue-Eintrag Outsource
Auslagerungs-Demo: Menue-Eintrag Outsource

Sie werden lediglich nach einem Routinennamen gefragt:

Auslagerungs-Demo: die Namensabfrage
Auslagerungs-Demo: die Namensabfrage

Das ist in den meisten Fällen alles, was Sie tun müssen! Structorizer analysiert automatisch, welche Argumente die Routine benötigt und ob sie einen Wert zurückgeben soll, verschiebt dann die Elemente in die neue Routine mit dieser Signatur und schiebt das Routinen-Diagramm in den Arranger. War das Hauptdiagramm zuvor noch nicht im Arranger, wird es dort ebenfalls abgelegt:

📷 Auslagerungs-Demo — das erstellte Unterprogramm für die Standardabweichung

Im ursprünglichen Diagramm werden die ausgelagerten Elemente durch den entsprechenden Routinenaufruf ersetzt. Das ersetzende CALL-Element wird automatisch ausgewählt (und damit hervorgehoben). Das Ergebnis ist sofort ausführungsbereit!

War das übergeordnete Diagramm noch nicht im Arranger, wird eine neue Gruppe erstellt, die nach ihm benannt ist. Das neue Unterprogramm-Diagramm wird automatisch allen Arrangement-Gruppen hinzugefügt, denen sein übergeordnetes Diagramm angehört.

Auslagerungs-Demo: der geaenderte Haupt-Algorithmus
Auslagerungs-Demo: der geaenderte Haupt-Algorithmus

Sieht das gut aus? Was ist aber mit Diagrammbereichen, die mehr als einen einzigen Wert erzeugen, auf den nachfolgender Code angewiesen ist? Versuchen wir es mit dem Eingabeteil — dieser führt sowohl die Variable count als auch das Array readings ein, die beide von nachfolgendem Code genutzt werden:

Auslagerungs-Demo: Auslagern der Eingabefolge
Auslagerungs-Demo: Auslagern der Eingabefolge

Da die zurückzugebenden Werte unterschiedliche Typen haben könnten, wäre es sauberer, einen dedizierten Record (Struct)-Typ für den Rückgabewert dieser Routine zu erstellen. Stattdessen nutzt der Konverter jedoch die Möglichkeit, Arrays ad hoc mit Werten unterschiedlicher Typen zu füllen (was in Structorizer einfacher ist, beim Export in einige Programmiersprachen aber Probleme verursachen kann).

Im Arranger wird das neue Unterprogramm ebenfalls Mitglied der Arrangement-Gruppe:

📷 Auslagerungs-Demo — Routine mit zwei Rückgabewerten

Wie wird der CALL im Hauptprogramm eingebunden? Ein Blick darauf:

Auslagerungs-Demo: Aufruf einer Routine mit mehreren Ergebnissen
Auslagerungs-Demo: Aufruf einer Routine mit mehreren Ergebnissen

Eine Array-Variable mit generischem Namen wird eingeführt, um die Werte aus der Routine entgegenzunehmen; die Werte werden dann einzeln extrahiert und in die eigentlichen Zielvariablen geschrieben. (Diese Methode mag nicht elegant wirken, ist in Structorizer aber sehr effektiv. Beim Export in streng typisierte Sprachen könnte es Probleme geben, wo stattdessen Record/Struct-Typen verwendet werden müssten. Eine spätere Version könnte das bereits mit Version 3.27 eingeführte Record-Konzept hier nutzen.)

Das Auslagern der Durchschnittsberechnung ist ebenso einfach wie zuvor:

Auslagerungs-Demo: Auslagern der Durchschnittsberechnung
Auslagerungs-Demo: Auslagern der Durchschnittsberechnung

So erhalten wir das dritte Unterprogramm im Handumdrehen.

📷 Auslagerungs-Demo — die ausgelagerte Durchschnittsberechnung

Das Hauptprogramm ist nach drei Auslagerungen erheblich geschrumpft:

Auslagerungs-Demo: Hauptprogramm nach drei Auslagerungen
Auslagerungs-Demo: Hauptprogramm nach drei Auslagerungen

Es muss wohl nicht erwähnt werden, dass das Auslagern im Hauptprogramm natürlich rückgängig gemacht (und wiederhergestellt) werden kann. Das Rückgängigmachen im übergeordneten Diagramm löscht jedoch nicht die erstellten Unterprogramme. Diese können einfach entfernt („fallen gelassen") werden, wenn man sie nicht mehr benötigt.

Die entstandene Gruppe von Diagrammen ist nun konsistent und kann als Arrangement gespeichert werden, indem man den Gruppeneintrag im Arranger-Index (rechtes Panel) auswählt und im Kontextmenü „Save changes" klickt. Sie können die Gruppe entweder als komprimiertes Archiv oder als Satz von NSD-Dateien mit einer referenzierenden Arrangement-Listendatei speichern:

Auslagerungs-Demo: Speichern der Gruppe
Auslagerungs-Demo: Speichern der Gruppe

Zugegeben, das war nur die halbe Wahrheit: Es gibt Fälle, in denen Structorizer die benötigten Parameter und Rückgabewerte möglicherweise nicht korrekt erkennt. In diesen Fällen müssen Sie das Ergebnis selbst nachbessern. Wir sind jedoch der Meinung, dass auch in diesen Fällen die Auslagerungsfunktion die Aufgabe der Zerlegung eines zu komplex gewordenen Algorithmus erleichtert.

Auslagern bei Record-Typen oder einbindbaren Diagrammen

Betrachten Sie den folgenden Algorithmus, der aus einem gegebenen Datum ein leicht abgewandeltes Datum ableitet (ohne Kalenderkorrektur). Hier ist ein Record-Typ beteiligt, den das Hauptprogramm und das ausgelagerte Unterprogramm gemeinsam nutzen müssen. Sie starten das Auslagern wie oben beschrieben:

Auslagern mit Record-Typen
Auslagern mit Record-Typen

Structorizer erkennt, dass der im Hauptprogramm definierte Typ Date auch dem Unterprogramm-Diagramm bekannt sein muss, und entscheidet daher, ihn in ein einbindbares Diagramm zu übertragen, das sowohl Hauptprogramm als auch Unterprogramm einbinden müssen. Daher werden Sie nach einem Namen für dieses zusätzliche Diagramm gefragt:

Auslagern: Namensabfrage fuer das einbindbare Diagramm
Auslagern: Namensabfrage fuer das einbindbare Diagramm

Nach Bestätigung erhalten Sie zwei neue Diagramme — das einbindbare und das Unterprogramm:

Auslagern mit einbindbarem Diagramm (Arranger-Ansicht)
Auslagern mit einbindbarem Diagramm (Arranger-Ansicht)

Das Hauptprogramm hat sich wie folgt verändert:

Fehlerhaftes Hauptprogramm nach dem Auslagern mit Record-Variable
Fehlerhaftes Hauptprogramm nach dem Auslagern mit Record-Variable

Wie im Analyser-Bericht zu sehen, ist das Ergebnis nicht ganz korrekt: Eine Record-Variable kann nicht einfach per Zuweisung eingeführt werden (außer wenn der zugewiesene Wert ein Record-Initialisierer ist). Es muss also eine Deklaration wie die ins Unterprogramm verschobene neu eingeführt werden (wo sie ebenfalls benötigt wird). Für die aktuelle Version von Structorizer ist eine automatische Lösung dieser Situation noch etwas zu komplex.

📷 Hauptprogramm nach Auslagern und manueller Korrektur

Übrigens: Wäre der Record-Typ vor dem Auslagern bereits im Hauptprogramm eingebunden gewesen (statt lokal definiert), hätte das Unterprogramm diesen Include-Eintrag automatisch geerbt, ohne Nachfrage.

Hinweis bezüglich der mit Version 3.29 eingeführten Arrangement-Gruppen: Beim Auslagern stellt Structorizer sicher, dass das abgeleitete Unterprogramm und ein mögliches einbindbares Diagramm automatisch allen Gruppen hinzugefügt werden, denen das Ursprungsdiagramm angehört, sodass die Konsistenz erhalten bleibt.

Gegenanzeigen für das Auslagern

Es gibt Algorithmus-Teilmengen, die nicht ohne Weiteres ausgelagert werden können. Diese entstehen üblicherweise durch unstrukturierte Diagramm-Elemente wie Sprünge (EXITs). Enthält der ausgewählte Bereich EXIT-Elemente, die den Kontrollfluss zu Zielen außerhalb der Auswahl lenken, entstehen ernsthafte Probleme.

Betrachten Sie folgendes Beispiel: Es enthält eine CASE-Auswahl mit verschiedenen Arten ausbrechender Elemente — das Verlassen der inneren Schleife, der äußeren Schleife, der gesamten Anwendung oder der aktuellen Routine bzw. des Programms:

Auslagerungs-Demo: Diagramm mit problematischen Sprungen
Auslagerungs-Demo: Diagramm mit problematischen Sprungen

Bei einem Versuch, die ausgewählten Elemente auszulagern, würden drei der Sprünge außerhalb der Teilmenge zeigen; nur der leere Sprung (äquivalent zu leave) hat ein Ziel innerhalb der Auswahl: die Eingabeanweisung unterhalb der FOR-Schleife. Der exit-Befehl ist kein Problem — seine Semantik ist unabhängig von seinem Ort, er bricht stets die gesamte Ausführung ab. Beim zweistufigen leave ist es anders: Sein Ziel ist die REPEAT-Schleife, die außerhalb der Routine läge und damit unerreichbar wäre; die Anweisung leave 2 wäre daher unzulässig. Die return-Anweisung hingegen würde ihre Semantik grundlegend ändern: Statt das äußere Programm zu beenden, würde sie nun lediglich das Unterprogramm verlassen und so die Programmlogik verletzen.

Structorizer versucht, solche Fälle zu erkennen, und warnt eindringlich vor dem Auslagern solcher Elementmengen:

Auslagerungs-Demo: Warnung bei problematischen Sprungen
Auslagerungs-Demo: Warnung bei problematischen Sprungen

Wenn Sie genau wissen, was Sie tun, und eine Idee haben, wie die durch das Auslagern verursachten Fehler behoben werden können, dürfen Sie fortfahren; andernfalls sollten Sie besser davon abs