Lade...
 

InstantView Scriptsprache

Die InstantView Scriptsprache

InstantView ist eine Programmiersprache, mit der mit minimalem Formalismus strukturiert betriebswirtschaftliche Anwendungen geschrieben werden können. Als interpretierte Sprache mit loser Kopplung und deklarativer Oberflächenbeschreibung eignet sie sich bestens für agile Softwareentwicklung mit kurzen Entwicklungszyklen. Dabei skaliert InstantView von einfachen Einzeilern bis hin zum Aufbau komplexer Anwendungen.

Um diese Komplexität abbilden zu können, wird InstantView als Teil der ClassiX-Architektur für besonders volatile, betriebswirtschaftliche und spezifische Aspekte der Anwendung eingesetzt, während das CyberEnterprise stabile, generische Funktionalität bietet. Gleichzeitig soll in InstantView primär semantisch gearbeitet werden statt technisch: Der Entwickler soll prozessorientiert denken können, statt sich mit der Technik auseinanderzusetzen. Durch Erlernen einer Skriptsprache kann die gesamte Anwendung für alle Endgeräte erstellt werden. Durch diese Trennung wird klarer strukturiert, welche Änderung an der Anwendung in welchem Teil durchzuführen ist.

Lose Kopplung

Bei Aufrufen von einem Modul zum anderen kann sowohl bei den ungerichteten Nachrichten als auch bei den gerichteten Provider-Aufrufen der Empfänger beliebig umgeändert werden.

Semantische Slots

Vordefinierte semantische Slots sind eine Kombination aus den harten Datenfeldern von Klassen und den unterspezifizierten Slots in prototypischen Sprachen: Jedes Objekt kann individuelle Datenfelder bekommen, die jedoch mit einer Bedeutung vorbelegt sind und sich somit selbst beschreiben.


Navigierendes Databinding

Um Verbindungen zwischen Objekten abzubilden, muss der Entwickler keine JOINs formulieren, sondern kann einfach mit einem entsprechenden Ausdruck die Verbindung von einem Objekt über dessen Member oder andere Relationen zum anderen navigierend beschreiben. Über eine solche Beschreibung können beispielsweise Oberflächenfelder gefüllt und deren Inhalte abgespeichert werden.


Deklarative Oberfläche

Ähnlich wie in HTML wird die Oberfläche in InstantView in ihrem Endzustand deklariert, statt wie bei GUI-Toolkits üblich, zusammengebaut zu werden. Es wird also beschrieben, was man erhalten möchte, nicht, wie man dort hinkommt. Hierdurch ist beim Lesen der Beschreibung auch sofort klar, wie die Oberfläche später aussehen wird und Anpassungen fallen leichter.


Vererbung

In InstantView können alle Komponenten spezialisiert werden, ohne das Verhalten der Basis abändern zu müssen. So können in einer Ableitung beispielsweise die Funktionsweise einer Prozedur angepasst oder aber Oberflächenelemente deklarativ hinzugefügt werden.


Objektorientiert

InstantView arbeitet mit in Objekten organisierten Daten. Auch von den zur Code-Organisation benutzten Modulen können neue Module zur Spezialisierung abgeleitet werden.


Interpretiert

Eine interpretierte Sprache bedeutet: kein Compiler, kein Build-Vorgang, dadurch schnelle Entwicklungszyklen. Außerdem können Anweisungen dynamisch zusammengesetzt und ausgeführt werden.

→ InstantView-Code kann interaktiv ausprobiert werden

Transparent Persistent

Zugriffe aus InstantView in die Datenbank sind transaktionsbasiert: Erst wenn ein Vorgang abgeschlossen ist, wird in die Datenbank geschrieben. Jedoch passiert dies ohne das Zutun des InstantView-Entwicklers und ohne eine objektrelationale Abbildung.


Stackbasiert

Zentraler Zwischenspeicher in InstantView ist der Stack. Hierdurch müssen keine Variablen benutzt werden und Aufrufe von Prozeduren, die auch mehrere Rückgabewerte haben können, können leicht verkettet werden.


Funktional

Auch aufrufbare Prozeduren können auf den Stack gelegt werden. Diese können dann wiederum in anderen Prozeduren benutzt werden im Sinne von Prozeduren höherer Ordnung.

 

Übersicht

Aufbau

Der unmittelbar sichtbare Teil von InstantView® sind Windowobjekte, von denen zurzeit 30 verschiedene existieren. Windowobjekte besitzen Aktionslisten, in denen die Dynamik der Anwendung als Reaktion auf Ereignisse festgelegt ist. Es gibt Systemereignisse und frei definierte Messages (letztere sind ein wichtiges softwaretechnisches Mittel zur Strukturierung komplexer Anwendungen in voneinander unabhängige Module).

Windowressourcen und Aktionen werden mit InstantView® definiert - einer einfachen Sprache, die, Bedürfnissen des Rapid Application Development entgegenkommend, so entworfen wurde, dass auch der vor allem an der Anwendung interessierte Nicht-Informatiker mit den Modellobjekten arbeiten kann. InstantView®(Script) soll leicht zu verstehen und anzuwenden sein - in dieser Hinsicht vielleicht mit BASIC vergleichbar. Einfache, überschaubare Konstrukte werden eleganten, aber komplizierten Lösungen vorgezogen:

  • Es gibt keine Typvereinbarungen. Variable haben den Charakter eines Containers, der Zahlen, Zeichenketten, Objekte usw. enthalten kann. InstantView® sorgt dafür, dass Operationen nur typgerecht ausgeführt werden - im Bedarfsfall wird eine Fehlermeldung generiert. Wird einer der arithmetischen Operatoren +, -, * und / auf ein Objekt angewendet, so muss das Objekt entscheiden, ob die Operation sinnvoll und ausführbar ist oder mit einer Fehlermeldung zurückgewiesen wird.
  • Logisch zusammengehörende Werte (Objekte, Zahlen, Zeichenketten) können als Vektor zusammengefasst werden.
  • Anweisungen haben maximal zwei konstante Parameter, mit denen die gewünschte Operation genauer spezifiziert wird. Variable Parameter werden über einen Stack vermittelt und das Resultat einer Anweisung wird auf dem Stack abgelegt.
     
  • Die Elemente des Stacks sind die gleichen Container, die für Variable benutzt werden. Warum ein Stack? Erstens, weil es ein sehr einfaches Konzept ist. Auch wer sich nie mit Programmierung befasst hat, kann sich eine InstantView®-Anweisung leicht als einen Automaten vorstellen, der im ersten Takt etwas von einem Stapel nimmt (natürlich von oben!), danach die gewünschte Aufgabe ausführt und zuletzt das Ergebnis auf dem verbliebenen Stapel ablegt. Ein Nachteil soll nicht verschwiegen werden: die Postfix-Notation. Um a und b zu addieren, muss statt der üblichen Notierung a + b jetzt a b + geschrieben werden (da '+' beide Operanden vom Stack nimmt und danach das Ergebnis dort ablegt). Komplexe arithmetische Ausdrücke sollten allerdings innerhalb der Memberfunktionen der Objekte berechnet werden. Natürlich muss man die sich ständig ändernde Belegung des Stacks beachten. Das kann lästig werden, wenn man Zwischenergebnisse über mehrere Anweisungen hinweg aufbewahrt. Aber dafür gibt es Variable! Weniger offensichtlichen sind folgende Vorteile der Stack-Architektur: Unterprogramme in InstantView® sind anwenderdefinierte Statements - sicher ein besseres Konzept als die GOSUB-Technik in BASIC, aber - genau wie in BASIC - ohne die Notwendigkeit, sich mit der Übergabe von Parametern zu befassen (call by value versus call by reference). InstantView®'s Message passing in Kombination mit dem Stack-Mechanismus erlaubt es, sehr einfach und elegant mit einer Message beliebige Daten zum Empfänger zu bringen.
  • Um ein Programm (lokal) zu strukturieren, gibt es die bekannten Konstrukte: Alternative (if, else), Zyklenbildung (do, while, loop), Auswahl (case) und Komposition (anwenderdefinierte Statements).
  • Module unterteilen größere Anwendungen. Jedes Modul schafft einen eigenen Namensraum für Variable und anwenderdefinierte Statements. Module besitzen alle Eigenschaften der Objektorientierung:
  • Kapselung: Unterschiedliche Module kommunizieren über Messages, die das Interface eines Moduls zur Außenwelt bilden. Um Module zusammenzufügen, müssen nur die akzeptierten Messages bekannt sein.
  • Vererbung: Von einem Modul können weitere Module abgeleitet werden. Das abgeleitete Modul erbt die im Basismodul definierten Windowressourcen und Aktionen, um diese zu ergänzen oder durch Neudefinition zu überschreiben.
  • Polymorphie: Alle geerbten Aktionen verhalten sich polymorph (Aktionen sind virtuell).

Module sind die Softwarebausteine auf der höchsten Abstraktionsebene. Aus ihnen kann sofort einen Anwendung zusammengestellt werden. Um auch sehr große Anwendungen zu unterstützen, wurden externe Moduldefinitionen eingeführt.

Ein intelligentes Mapping zwischen Window- und Modell-Objekten steuert den Datenaustausch zwischen Modell und Oberfläche. Die Visualisierung der Modelldaten wird einfach und effektiv (FillWindow, DrainWindow). Die Bindung zwischen View und Modell beschreibt ein Zugriffsausdruck, mit dem  u.a. Relationen verfolgt und Funktionen aufgerufen werden können.

Die meisten Modellklassen von InstantView® haben die Fähigkeit, neben  den durch die C++-Klassendefinition statisch festgelegten Daten auch  dynamische Daten - Slots - zu halten. InstantView® sorgt dafür, dass Slots wie 'normale' Datenmember erscheinen. Slots können in einem  Zugriffsausdruck erscheinen oder bei der Formulierung einer Query benutzt  werden. Das Mapping zwischen Modell und Oberfläche trägt dem Umstand  Rechnung, dass ein Slot nicht notwendigerweise in allen Instanzen einer  Klasse vorhanden sein muss (volatile window objects).

InstantView® ist eine interpretierte Sprache. In InstantView® beschriebene Anwendungen werden beim Programmstart in ein zur Laufzeit sehr schnell  interpretierbares internes Format übersetzt.

Interaktion mit der GUI

InstantView® Skript beschreibt u.a. Window-Ressourcen, die in reale Windowobjekte von Windows transformiert und damit zur Darstellung auf dem Bildschirm gebracht werden. Vom GUI empfangene Messages werden in logische Events (d.h. in die bei InstantView® vorgesehenen System-Events) übersetzt. Logische Events starten die in Aktionslisten beschriebenen Algorithmen.

Wie jedes andere ereignisgesteuerte Programm verweilt InstantView® in einem Programmzyklus, auf Messages vom Basissystem (MS Windows) wartend. Sobald der Anwender einen Button drückt, ein Menüitem auswählt oder etwas Ähnliches tut, erhält InstantView® für das betroffene Windowobjekt (den Button, das Menüitem, ...) eine Message, übersetzt diese in ein logisches (und daher plattformunabhängiges) Ereignis. Dann wird die Aktionsliste des Windowobjekts durchsucht.

Gibt es dort eine an das logische Event gebundene Anweisungsfolge, soll diese natürlich ausgeführt werden. Das geschieht auch, aber nicht sofort. Unter Umständen könnte jetzt ein zeitaufwendiger Prozess starten - aber InstantView® beantwortet in diesem Moment eine Message des Basis- Windowsystems! Deshalb wird die Aktion zeitlich entkoppelt: die InstantView®-Anweisungen passieren eine Warteschlange. Dieser Umweg ist für den InstantView®-Programmierer transparent, erlaubt ihm aber, für ein Systemereignis beliebige Aktionen zu definieren ohne sich dabei um Zeitbedingungen zu kümmern.

Die folgende Abbildung zeigt den Zusammenhang Message - logisches Ereignis - Aktion für ein Window mit Button. Wird der Button gedrückt, ändert sich der Titel des Windows, in unserem einfachen Beispiel wird der Titel "My Window" in Klammern gesetzt:
 

eventflow.jpg

 

Parameter stack

InstantView® Skript Anweisungen tauschen Parameter und Ergebnisse über einen Stack aus. Jede Anweisung konsumiert eine exakt definierte Anwahl von Stackeinträgen und legt anschließend ihre Ergebnisse dort ab. Die folgende Abbildung zeigt die Stackbelegung für das vorangegangene Beispiel:

stack.jpg

Garbage Collection

InstantView® entfernt automatisch Daten, die von einer durch ein Event getriggerte Anweisungsfolge auf dem Stack hinterlassen werden. Die Daten, die auf dem Stack liegen oder von Variablen gehalten werden, belegen Speicher. Dieser Speicher wird frei, sobald die Einträge vom Stack genommen oder den Variablen andere Werte zugewiesen werden. InstantView® startet von Zeit zu Zeit einen Garbage-Collection-Prozess, der solche Speicherbereiche zurückgewinnt.

Für elementare Datentypen (ganze Zahlen, Zeichenketten, multiple Zeichenketten, ...) geschieht dies automatisch; es gibt keinen Grund, diesen Vorgang überhaupt zur Kenntnis zu nehmen. Aber auch der Speicher, den ein transientes Objekt X einst belegt hat, soll freigegeben werden. Der Garbage-Collection-Algorithmus kann - zumindest in diesem Release - nicht feststellen, ob X von einem weiteren (transienten) Objekt Y referenziert wird. Solange X und Y auf dem Stack liegen oder Variablen zugewiesen sind, ist alles gut. Wird dann nur X frei, enthält Y nach der nächsten Garbage-Collection eine Referenz auf ein nicht existentes Objekt. Dies zu verhindern gibt es zwei Möglichkeiten:

  • dafür sorgen, dass das referenzierte Objekt X in einer Variablen gehalten wird (solange Y existiert)
  • X explizit von der Garbage-Collection ausschließen  (siehe CreateTransObject) und später selbst (mit DeleteObject) freigeben Dieses Problem betrifft auch (transiente) Objekte als Rückgabewert einer Funktion: Die im MDI angegebene Signatur bestimmt, ob InstantView® das Objekt von der Garbage-Collection ausschließt oder nicht.


Interaktion mit Modell-Objekten

Modell-Objekte sind Instanzen in C++ geschriebener Klassen, und daher gibt es keine inhärente Möglichkeit, zur Laufzeit (mit Nicht-C++-Code) auf Daten und Methoden zuzugreifen. InstantView® braucht aber genau solch einen Zugang. Deshalb können Modell-Klassen um ein Data Dictionary (DDI) und ein Method Dictionary (MDI) erweitert werden.

InstantView® besitzt Anweisungen, die Daten aus einem Objekt auf den Stack bringen oder umgekehrt Daten vom Stack in ein Objekt speichern. Das DDI beschreibt, welche Relationen zwischen Objekten mit InstantView® erzeugbar sind (und garantiert damit referentielle Integrität). Es ist die Grundlage für das intelligente Mapping zwischen Modell-Objekt und Windowoberfläche über Zugriffsausdrücke (siehe FillWindow und DrainWindow).

Mit der Anweisung Call können Funktionen eines Objektes aufgerufen werden, wenn sie im MDI eingetragen sind. Das gilt auch für Funktionsaufrufe innerhalb eines Zugriffsausdrucks. (Sowohl DDI als auch MDI einer Klasse werden mit Utility GENDDI automatisch generiert).
 

Interaktion mit dem Objektmanager

Will InstantView® ein persistentes Objekt erzeugen / löschen, eine Query starten usw., so fordert es diese Dienste nicht direkt von der objektorientierten Datenbank sondern stützt sich auf den Objektmanager. ClassiX® sieht die Aufteilung der Datenbank in Layer und Domains vor, Objekte können sogar in unterschiedlichen physischen Datenbanken gespeichert sein.

Das Layout einer Datenbank wird im File CLASSIX.INI beschrieben, das der Objektmanager in der Initialisierungsphase liest. Nur der Objektmanager 'weiß', wo ein Objekt einer bestimmten Klasse gespeichert werden muss und wo es wiedergefunden werden kann.
 

Message passing

Wird (mit SendMsg) eine Message ausgesendet, so durchsucht InstantView® zuerst die Aktionslisten aller Module, danach aller Windowobjekte nach Anweisungen, die mit der ausgesendeten Message verbundenen sind. Gefundene Anweisungen werden sofort - ohne den Umweg über eine Warteschlange - ausgeführt. Nur die zurzeit geöffneten Windows und deren Childobjekte können eine Message empfangen. Folglich müssen, wenn eine Message ein Window öffnen soll, die entsprechenden Anweisungen entweder einem Modul oder einem anderen Window, das sich bereits auf dem Bildschirm befindet, zugeordnet sein. Das eine Message sendende Windowobjekt kann auch zu den Empfängern dieser Message gehören.

Wie transportiert eine Message weitere Information? Die erste Anweisung einer Folge, die durch ein System-Ereignis aktiviert wurde, sieht einen leeren Stack. Das gilt nicht notwendigerweise für die erste der durch eine Message getriggerten Anweisungen. Bei jedem Empfänger erscheint genau die Stackbelegung, die SendMsg vorgefunden hat. SendMsg nimmt alle Einträge vom Stack. Die Empfänger einer Message können mit Anweisung ReturnStack ihren Stack an den Sender zurückgeben.

Die gleiche Anweisungsfolge kann von System-Ereignissen und Messages getriggert werden. Wie bei System Events, so dürfen auch die Empfänger einer Message Daten auf dem Stack hinterlassen (InstantView® entfernt sie automatisch).

SendMsg verteilt seine Message wie ein Rundschreiben. Will man ein Protokoll aufbauen, wo der Empfänger dem Sender direkt antwortet (unter Ausschaltung aller anderen potentiellen Mithörer), so muss die primäre Message neben eventuell anderen Daten auch das sendende Windowobjekt enthalten. Ein Windowobjekt wird mit Anweisung Widget auf den Stack gebracht. Der Empfänger kann nun mit SendMsg(,DIRECT) gezielt antworten.

Weitere Themen