Heiner KückerAlgorithmische Symmetrie in Java |
|
Home Java-Seite Weiterentwicklung_Java NullPointer Algorithmische Symmetrie Finder_Feature Multiple_Interface Implementationen Proxy_Methoden Speicher_Klassen WebCam_Demo JSP WorkFlow PageFlow FlowControl Page Flow Engine Control_and_Command JSP_Spreadsheet Domain Parser Codegenerator_für hierarchische Datenstrukturen Expression_Engine Formula_Parser State Transition Engine AspectJ Java_Explorer DBF_Library Kalender_Applet SetGetGen BeanSetGet CheckPackage LineNumbers GradDms Excel-Export StringTokenizer JspDoc JspCheck JSP-Schulung Java Server Pages Struts AsciiTabellenLayouter StringSerial Silbentrennung JDBC_Schlüssel- Generierung bidirektional/ unidirektional gelinkte Liste Java_Sitemap Generator XmlBuilder RangeMap Alaska-XBase++-Seite Projekte Philosophien Techniken Konzepte Sudoku Kontakt / Impressum Links SiteMap Letzte Aktualisierung: 24.08.2002 |
Algorithmische SymmetrieIn fast allen Programmen gibt es Code-Teile, in denen Ressourcen angefordert werden und wieder abgegeben werden müssen. Typisch sind auch Codings die aus Vorbereitung, eigentlicher Abarbeitung und Endebehandlung bestehen. Zum Beispiel muss eine Datei vor der Bearbeitung geöffnet werden und nach der Bearbeitung wieder geschlossen werden. Die Bearbeitung ist nur zwischen Öffnen und Schliessen möglich. Ähnliches gilt für JDBC-Connections. Auch Schleifen brauchen meist eine Anfangs- und Endbehandlung und haben einen Code-Körper. Dafür ist ein Sprachmittel, welches die Einhaltung der algorithmischen Symmetrie per Compiler-Prüfung absichert, wünschenswert. Anforderung/Öffnen/Initialisieren { Benutzung } Rückgabe/Schliessen/RücksetzenDas Sprachelement könnte folgendermassen aussehen: File myFile = new File("xxx"); | File myFile = new File("xxx"); | begin myFile | myFile.open(); { | { myFile.read(); | myFile.read(); myFile.write("yyy"); | myFile.write("yyy"); } | } end myFile | myFile.close();Sinnvoll ist die Kombination des begin-end-Blocks mit einem try-finally-Block, um zu sichern, daß die Anweisungen des end-Blockes auch beim Werfen einer Exception ausgeführt werden. Man könnte auch sagen, die algorithmische Symmetrie über den begin-end-Block ist eine Erweiterung der try-finally-Konstruktion um Anfangsbehandlung und Code-Wiederverwendung. File myFile = new File("xxx"); | File myFile = new File("xxx"); | begin myFile | myFile.open(); | try{ | myFile.read(); | myFile.read(); myFile.write("yyy"); | myFile.write("yyy"); | end myFile | }catch(Exception e){ | Log.exception(e); | }finally{ | myFile.close(); | }Die begin- und end-Blöcke sollten im Source-Code der entsprechenden Klasse deklariert werden. Dabei muß der Scope beachtet werden. Wenn die begin- und end-Blöcke Methoden sind, können sie die Variablen in der benutzenden Methode nicht sehen. Entweder das kontrollierte Objekt wird als Referenz übergeben oder der Code wird per include eingefügt. Da die Bearbeitung nur im Block erlaubt ist, ist ein Sprachmittel zum Erlauben der Benutzung nur im Block sinnvoll. public blocked void write(String parStr){ ... }Das zusätzliche Schlüsselwort "blocked" sorgt dafür, daß die Methode nur innerhalb eines Blockes auf das entsprechende Objekt verwendet werden darf. Für den Fall, daß die Operationen auf dem blockierten Objekt in Methoden zusammengefasst werden, benötigt man ein Sprachmittel zum Delegieren der Benutzungs-Erlaubnis in Methoden. public void writeln(blocked File parFile,String parStr){ parFile.write(parStr); // blocked method parFile.write("\n"); // blocked method }Meine Überlegung ist, das Blockieren an den Parameter und nicht an die Methode zu binden. Der Compiler darf die Verwendung nur in einem Block auf das entsprechende Parameter-Objekt erlauben. Eine andere Möglichkeit ist die Verwendung eines Macro-Prozessors. Der Macro- Prozessor arbeitet nach folgendendem Prinzip: Definition des Macros: macro WRITE <name>, <outStrExpression> <name>.write(<outStrExpression>) macroendVerwendung im Quelltext: WRITE outFile , strOut ;Auflösung durch Macro-Prozessor: outFile.write( strOut ) ;
VorteileDie Includierung der Macros durch einen Pre-Prozessor erlaubt Code-Bausteine, die Struktur-Elemente (typisch die Brackets { und } ) enthalten. Das können try- catch-finally-Blöcke, if-, for-, while- und do-while Strukturen sowie Blöcke für beschränkte Variablensichtbarkeit sein. Das ist mit Methoden oder Objekten nicht möglich.
NachteileEinige Fehler werden erst vom Java-Compiler gefunden. Hier kann durch bessere Prüfungen im Pre-Prozessor etwas entlastet werden.Erst eine Integration des Pre-Prozesors in den Java-Compiler erlaubt die richtige Zuordnung der Zeilen-Nummern bei Syntax- und Laufzeitfehlern. Wünschenswert ist eine Zeilenangabe Source-Zeile:Macro-Zeile.
notwendige ErweiterungenIm jetzigen MacroProcessor-Prototyp ist noch keine Validierung eingebaut. Die Kontrolle auf die Verwendung bestimmter Makros nur innerhalb von anderen Makro-Klammern könnte mit Techniken analog zur Tag-Validierung von JSP-Tags erfolgen. Es bietet sich die passive Validierung über bestimmte Schalter, Ausdrücke oder reguläre Ausdrücke beziehungsweise aktiv über spezielle Validierungs-Klassen, die vom Preprozessor geladen und mit einer Referenz auf den Source-Kontext gestartet werden.Zur Schachtelung von Makros ist ein Mechanismus zum Bereitstellen der Schachtelungstiefe sinnvoll. Dadurch können zum Beispiel Laufvariablen unterschieden werden ( i<depth> -> i0, i1, i2 ...).
ProblemeDie Bereitstellung dieses Features verhindert nicht den unmittelbaren Zugriff auf die in den Makros verwendeten API-Funktionalitäten. Man bräuchte also noch eine Möglichkeit zum Abschalten (Kapseln) von API-Methoden. Das passt zur OOP-Kapselung und erweitert diese.
Macro-Processor PrototypHier der in einem sehr frühen Entwicklungsstdium befindliche Pre-Prozessor für die Macro-Ersetzung. Je nach Zeit werde ich diesen weiterentwickeln.
Download der Quelldateien AlgoSymm.zip
Achtung: Erweiterungen und Fixes stelle ich ohne Historie
und ohne Ankündigung hier bereit. Lizenzbedingungen:
Die Programme, Quelltexte und Dokumentationen können ohne
irgendwelche Bedingungen kostenlos verwendet werden. |