Großer Beleg über das Thema Speicherformate und Datenhaltung in einem medizinischen Dialogsystem an der Technischen Universität Dresden Fakultät Informatik Institut für Künstliche Intelligenz Lehrstuhl Applied Knowledge Representation and Reasoning bearbeitet von Martin Höher geboren am 04. 06. 1988 in Löbau Matrikel-Nr.: 3391239 Hochschullehrer: Doz. Dr.-Ing. habil. Uwe Petersohn Betreuer: Doz. Dr.-Ing. habil. Uwe Petersohn Begonnen am 1. Mai 2011 Eingereicht am 31. Oktober 2011 Inhaltsverzeichnis 1. Einleitung 7 2. Nutzen medizinischer Dialogsysteme 2.1. Funktionsweise . . . . . . . . . . . . 2.2. Hypothetischer Nutzen in der Praxis 2.3. Realität? . . . . . . . . . . . . . . . . 2.4. Anforderungen an ein Dialogsystem 2.5. Daten der iSuite . . . . . . . . . . . . . . . . . 9 9 10 10 11 12 . . . . . . . . . . . . . . 16 17 17 18 20 20 25 26 27 28 28 30 30 34 36 4. Integration und Refactoring einer Dialogkomponente 4.1. Ausgangssituation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1. Die (alte) iSuite . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.2. Überarbeitete Dialogkomponente . . . . . . . . . . . . . . . . . 39 39 39 40 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3. Speicherformate und Datenhaltung 3.1. Das perfekte Dateiformat? . . . . . . . . . . . . . . 3.2. Vergleich gängiger Formate . . . . . . . . . . . . . 3.2.1. Binärdateien . . . . . . . . . . . . . . . . . . 3.2.2. Proprietäre Textformate . . . . . . . . . . . 3.2.3. Extensible Markup Language . . . . . . . . 3.2.4. Datenbanken . . . . . . . . . . . . . . . . . 3.2.5. Ausblick . . . . . . . . . . . . . . . . . . . . 3.2.6. Zusammenfassung . . . . . . . . . . . . . . 3.3. Organisation der Datenhaltung in Anwendungen 3.3.1. Direkter Zugriff auf Dateien . . . . . . . . . 3.3.2. Abstrahierter Zugriff . . . . . . . . . . . . . 3.3.3. Die Repository-Metapher . . . . . . . . . . 3.3.4. Zentrale vs. Dezentrale Datenhaltung . . . 3.3.5. Zusammenfassung . . . . . . . . . . . . . . 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inhaltsverzeichnis 4.2. 4.3. 4.4. 4.5. 4.1.3. Aufgabe dieser Arbeit . . . . . . . . . Analyse . . . . . . . . . . . . . . . . . . . . . . 4.2.1. Datenbasis . . . . . . . . . . . . . . . . 4.2.2. Kompatibilität zu alten Komponenten 4.2.3. Stand der neuen Dialogkomponente . 4.2.4. Schlußfolgerungen . . . . . . . . . . . Integrationsphase . . . . . . . . . . . . . . . . 4.3.1. iSuite.KnowledgeBase.Data . . . . . . 4.3.2. Das Pluginsystem . . . . . . . . . . . . Neue und angepasste Applikationen . . . . . 4.4.1. Dialogkomponente . . . . . . . . . . . 4.4.2. KnowledgeBase Converter . . . . . . 4.4.3. MigTool . . . . . . . . . . . . . . . . . 4.4.4. KnowledgeBase Editor . . . . . . . . . Schlußphase . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5. Zusammenfassung und Ausblick 5.1. Was wurde geschafft? . . . . . . . . . . . . . . . . . . . . . . . . 5.2. Weitere Schritte . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.2.1. Klärungsbedarf bei der Lizenz der C#Prolog Bibliothek 5.2.2. Nutzen des XML Formates . . . . . . . . . . . . . . . . 5.2.3. Weitergehendes Redesign und Neuentwicklungen . . . 5.2.4. Anpassung der Datenbankschemata . . . . . . . . . . . 5.2.5. Ausbau des Editors für die Wissensbasis . . . . . . . . 5.3. Lessons Learned . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.1. Analysephase bei größeren Projekten ist wichtig . . . . 5.3.2. Abstraktion der Datenhaltung . . . . . . . . . . . . . . 5.3.3. Design Pattern vs. Ease of Code . . . . . . . . . . . . . A. Literatur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 40 40 41 41 42 42 43 43 47 47 48 48 48 49 . . . . . . . . . . . 51 51 51 52 53 54 54 54 55 55 55 55 57 3 Abbildungsverzeichnis 2.1. Schematischer Überblick über die Datenhaltung in Anwendungen . . 13 3.1. 3.2. 3.3. 3.4. . . . . 21 23 31 33 4.1. Klassendiagramm Container“ . . . . . . . . . . . . . . . . . . . . . . . ” 4.2. Wissensbasis mit Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 45 Binäreditor Okteta“ . ” Texteditor Kate“ . . . ” White Box Repository . Black Box Repository . . . . . . . . . . . . . . . . . . . . . . . . . 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tabellenverzeichnis 3.1. Vergleich ausgewählter Dateiformate und Vorgehen . . . . . . . . . . . 3.2. Zusammenfassung Repositorytypen . . . . . . . . . . . . . . . . . . . . 5 29 38 Aufgabenstellung Die Aufgabe dieser Arbeit bestand darin, die bereits neugestaltete Dialogkomponente zum Abfragen von Patientendaten in das Gesamtsystem der iSuite einzubetten – ein System, welches zur Unterstützung der Betreuung von Schmerzpatienten entwickelt wurde. Hauptaugenmerk bestand dabei auf der Bereitstellung einer neuen Datenabstraktionsschicht, die eine möglichst hohe Abgrenzung vom eigentlich genutzen Speicherformat bieten sollte. The main task of this work was to embed the already redesigned dialog system into the iSuite – an application suite for serving the special needs of patients suffering of chronic pain. Consequently, an abstraction library has been developed, encapsulating the concrete data storage formats allowing to easily exchange them and keeping the dialog system itself independent of it. 6 1. Einleitung Diese Arbeit soll sich vor allem mit einem beschäftigen: Den Daten, die zu den meisten Anwendungen gehören. Freilich gibt es Programme, die sozusagen selbstenthalten sind – die nur die eigene, ausführbare Datei mitbringen. Die Regel aber ist eine andere; gerade größere Programme benötigen hunderte Dateien, die zur korrekten Ausführung benötigt werden. Das betrifft Texteditoren genauso wie Mediacentersoftware. Auch der Diskursbereich, der dieser Arbeit zu Grunde liegt, macht keine Ausnahme: Die praktischen Arbeiten, zu denen dieser Text ebenfalls eine Art Dokumentation bildet, sind im medizinischen Bereich angesiedelt. Es geht um ein Dialogsystem mit primären Fokus auf der Behandlung von Patienten mit chronischen Schmerzen. Die praktische Arbeit bestand in erster Linie darin, die neuentworfene Version der eigentlichen Dialogkomponente in das bestehende Gesamtsystem der iSuite einzubetten. Die Dialogkomponente ist dabei dafür zuständig, die vorliegenden Fragenkataloge in einer benutzerfreundlichen Art und Weise anzuzeigen, um so vom Patienten Wissen zu seinem aktuellen Gesundheitszustand (und weiteren Dingen, wie etwa andere beteiligte Ärzte, Krankenkasse, usw.) abzufragen. Andere Komponenten in der iSuite können dann dazu genutzt werden, dieses Wissen aufzubereiten, um so den behandelnden Arzt zu unterstützen. Beide Parts waren dabei jeweils für sich problemlos ausführbar. Allerdings gab es keine (direkte) gemeinsame Datenquelle. Dieses Manko sollte mit dieser Arbeit beseitigt werden. Dabei ist eine neue Zwischenschicht entwickelt worden, die auch zukünftigen Änderungen und wechselnden Anforderungen leicht genügen sollte. Diese Arbeit wird nun wie folgt vorgehen: Im ersten Teil soll kurz allgemein auf das Thema Dialogsysteme speziell im medizinischen Kontext eingegangen werden. Dabei sollten insbesondere schon einmal Anforderungen herausgearbeitet werden, um sie im zweiten Teil genauer zu vertiefen. In diesem soll es dann auch primär um das Thema Datenspeicherung und Dateiformate gehen. Es gilt verschiedene Modelle und Vorgehensweisen vorzustellen und deren Vor- und Nachteile gegeneinan- 7 KAPITEL 1. EINLEITUNG der aufzuwiegen. Ziel dieses Kapitels soll es dabei sein, dem geneigten Leser einen Einblick und grundlegende Möglichkeiten zu geben, die es ihm erlauben, bestehende Architekturen besser analysieren und verstehen zu können bzw. ihm das nötige Wissen in die Hand geben, um selbst flexible Lösungen entwerfen zu können. Der dritte große Teil dieser Arbeit wird dann noch einmal genauer auf die zu Grunde liegende praktische Arbeit eingehen. Designentscheidungen werden beschrieben und erläutert, warum genau diese getroffen wurden bzw. wie sich andere Entscheidungen auswirken würden. Damit ist dieser Teil gleichsam eine Art Dokumentation der Arbeit. 8 2. Nutzen medizinischer Dialogsysteme Da die – dieser Arbeit zugrunde liegende – praktische Aufgabe im medizinischen Bereich angesiedelt ist, soll im folgenden Kapitel kurz auf die allgemeine Thematik intelligenter Dialogsysteme (mit dem besonderen Blick in den medizinischen Bereich) eingegangen werden. Dabei soll bereits auf die eigentliche Thematik hingewiesen werden, d.h. es werden Anforderungen dieser Art von Anwendungen bzgl. verwendeter Speicherformate angesprochen. 2.1. Funktionsweise Ein Dialogsystem dient in erster Linie dazu, eine in einem beliebigen Speicherformat abgelegte Folge von Fragen anzuzeigen und vom Nutzer Atworten einzusammeln. Rein prinzipiell ist das Verfahren von Fragenkatalogen auf Papier bekannt. Allerdings ist der Vorteil bei einer Umsetzung in einem Computersystem, dass das System dynamisch auf bereits gegebene Antworten eingehen kann. So kommt es oft vor, dass das Stellen einer Frage eigentlich nur dann Sinn macht, wenn der Befragte zuvor eine andere Frage positiv beantwortet hat. Ein gutes Beispiel sind – im medizinischen Umfeld – geschlechtsspezifische Fragen: Es macht eigentlich keinen Sinn, eine für männliche Patienten gedachte Frage einer Frau zu stellen. Erfragt man zuvor jedoch das Geschlecht, kann man solche Fragen auslassen. Das spart Zeit und Nerven des Patienten. In der Papiervariante bleibt an dieser Stelle lediglich der Verweis (etwa durch eine eingezogene Überschrift), dass der folgende Fragenblock an die Beantwortung einer vorangegangenen Frage gekoppelt ist. Nach Beenden des eigentlichen Dialogsystems liegen die Daten sofort im Rechner vor – das heißt, weitere Komponenten können diese ohne Verzögerung auswerten. Wenn die Beantwortung der Fragen durch einen Fragebogen auf Papier basieren 9 KAPITEL 2. NUTZEN MEDIZINISCHER DIALOGSYSTEME würde, müssten die Antworten erst eingelesen werden (etwa durch Einscannen und anschließender Auswertung durch ein Bildverarbeitungsprogramm). 2.2. Hypothetischer Nutzen in der Praxis Richtig angewandt, könnten diese Dialogsysteme äußerst nützlich sein. Oft ergeben sich fast zwangsläufig Wartezeiten; warum diese also nicht vernünftig nutzen und den Patienten während des Wartens die Fragen beantworten lassen? Das Dialogsystem – oder genauer die Auswertekomponenten – könnten dann die Daten auswerten um dem Arzt einen Report anzeigen, den dieser beim eigentlichen Gespräch mit dem Patienten nutzen kann, um sofort wirklich wichtige Fragen stellen und mit benötigten Untersuchungen beginnen zu können. Je nach Betrachtungswinkel verkürzt dies die Behandlungszeit des einzelnen Patienten (genauer die Zeit, die der Arzt mit diesem Patienten beschäftigt ist) bzw. ermöglicht eine bessere Behandlung im selben Zeitrahmen. Ebenfalls kann ein solches System zur Dokumentation genutzt werden. Dass heißt, die Ergebnisse der Befragung werden (in einer Zusammenfassung) ausgedruckt und etwa von Arzt und Patient unterschrieben. Damit sind – im Falle von Rechtsstreitigkeiten – klare Verhältnisse gegeben. 2.3. Realität? In der Realität werden solche Dialogsysteme noch nicht sehr verbreitet genutzt. Während in den Praxen zwar durchaus die Computertechnik schon seit einiger Zeit Einzug gehalten hat, ist gerade bei den Patienten die Akzeptanz für solche Systeme nicht immer gegeben. Vor allem Menschen, die schlicht nicht mit den neuen Techniken aufgewachsen sind, stehen solchen Systemen kritisch gegenüber bzw. sind sie schlicht nicht in der Lage, mit gängigen Computersystemen umzugehen. Ein weiteres Problem: Gerade im medizinischen Bereich werden oft (unbewusst) falsche Antworten gegeben. Ein typisches Beispiel: Der Patient wird nach Herz- und Kreislauferkrankungen gefragt. Viele verneinen diese Frage und geben an, diesbezüglich keine Probleme zu haben. Wird danach nach Bluthochdruck gefragt, ist die Antwort dennoch positiv. Schlußendlich bedeutet das, dass die Dialogsysteme bzw. die Auswertekomponenten solche Fakten beachten müssen und vor allem darf sich 10 KAPITEL 2. NUTZEN MEDIZINISCHER DIALOGSYSTEME ein Arzt nicht komplett auf ein solches System verlassen (es soll entscheidungsunterstützend, aber nicht -gebend sein). Ein ganz anderes Problem kommt von Seiten der Ärzte: Denn diese lehnen die Nutzung computergestützter Systeme wie der iSuite oft eher ab. Hier sind wohl vor Allem Zeit und Kosten als Gründe anzunehmen – in der Tat ist die Einführung eines solchen Systems mit einem gewissen Einarbeitungsaufwand verbunden. Tatsächlich sehen die meisten Mediziner, welche den Einsatz solcher Systeme in Erwägung ziehen, den größten Nutzen eher in der Dokumentation des Gesundheitszustandes des Patienten, was gewisse Vorteile bietet, wenn es zu Streitigkeiten kommt, weil ein Patient der Meinung ist, vom Arzt falsch behandelt worden zu sein. 2.4. Anforderungen an ein Dialogsystem Ein gutes Dialogsystem sollte also vor allem auf gute Usability achten, um die Akzeptanz bei Patienten (oder allgemein Nutzern) zu erhöhen. Das betrifft etwa die Eingabemöglichkeiten (sie müssen erkennbar, nachvollziehbar und robust sein) aber auch sofort einen ersichtlichen Nutzen für die Befragten bieten (da andernfalls die Annahme durch die Patienten fraglich ist – aus deren Sicht wäre es sinnfrei, sich auf etwas fremdes einzulassen, wenn es keinen offensichtlichen Vorteil gegenüber herkömmlichen Mitteln gibt). Bei einem Fragebogen auf Papier ist es nur begrenzt möglich, Abbildungen zu nutzen. Bei einem elektronischen System kann jede Frage einzeln gestellt werden, d.h. man hat den gesamten Bildschirm um etwa mit zusätzlichen Erläuterungen und Abbildungen dem Nutzer die Entscheidung für eine Antwortmöglichkeit zu erleichtern. Schon das kann, vernünftig genutzt, einen Vorteil für die Patienten bedeuten. Weiterhin sollte auch die Möglichkeit, Fragen bedingt zu stellen, ausgiebig genutzt werden, um dem Nutzer das Beantworten von Fragen zu ersparen, deren Antworten ohnehin nicht von der Inferenzkomponente herangezogen werden. Im Hintergrund gibt es aber noch weitere wichtige Fragen. Etwa nach dem Format, in dem die Wissensbasis – sprich die Dialoge und damit verbundene Daten, die dann zur Aufbereitung des Wissens dienen – gespeichert wird. Diese Frage ist nicht unerheblich: Denn hier gibt es eine Schnittstelle zwischen den Fachbereichen IT und Medizin. Während zwar der Informatiker mit allen möglichen Speicherformaten klarkommen kann, wird sich ein Mediziner schwer tun. Das bedeutet also, dass hier ein möglichst klares und leicht verständliches Format zur Speicherung der Da- 11 KAPITEL 2. NUTZEN MEDIZINISCHER DIALOGSYSTEME ten gewählt werden sollte. Für das intelligente Dialogsystem liegt der Schluss nahe, als Format zum Speichern direkt eine Logiksprache wie Prolog zu verwenden. Das macht Sinn, da dann beispielsweise Bedingungen für das Stellen von Fragen sehr leicht zu modellieren sind. In der Anzeigekomponente könnte dann direkt ein Prologinterpreter genutzt werden, um die Wissensbasis auszuführen“. Auf der anderen ” Seite wird das Wissen aber auch in anderen Komponenten benötigt, bei denen Prolog als Laufzeitumgebung nicht die beste Wahl ist. Diese müssen dann die Dateien selbst parsen oder umständlich einen eingebetteten Prologinterpreter abfragen, um an die Informationen zu gelangen. Für das Speicherformat können also die folgenden Punkte herausgestellt werden: • Die Datenbasis sollte möglichst über verschiedene Komponenten hinweg verfügbar sein – unabhängig von deren Laufzeitumgebung. • Das Format der Daten sollte leicht verständlich sein; selbst wenn gute Editoren vorliegen, ist es günstig, sich die Möglichkeit offen zu halten, die Dateien per Hand editieren (bzw. damit auch debuggen) zu können. Des weiteren hat ein einfaches Format auch den Vorteil, dass es nicht von einem Fachexperten aus dem Bereich IT geschrieben werden müsste, sondern direkt von einem Mediziner, der durch sein domänenspezifisches Wissen besser in der Lage ist, die Daten und Zusammenhänge in das System einzuspeisen. Der Zweite Punkt schließt aber auch einen speziell für diesen Zweck entwickelten Editor nicht aus – würde dieser doch das Editieren für Nicht-Informatiker deutlich erleichtern. Dennoch: Je einfacher und leichter das Format zu verstehen und editieren ist, desto besser. 2.5. Daten der iSuite Um für die in den nächsten Kapiteln folgenden Ausführungen besser verstehen zu können, soll hier kurz ein Einblick in die Datenhaltung der iSuite gegeben werden. Für tiefergehende Informationen sei hier auf [17] verwiesen. Neben den üblichen Daten (Bilddateien, Konfigurationen, etc.) gibt es vor allem zwei Schwerpunkte: Zum Einen benötigt die iSuite eine baumartige Struktur, in der statisches Wissen zu Anamnesen, Befunden, Diagnosen und so weiter abgelegt sind. Zur Identifikation einzelner Knoten werden semantische Schlüssel verwendet, d.h. ein 12 KAPITEL 2. NUTZEN MEDIZINISCHER DIALOGSYSTEME Abbildung 2.1.: Schematischer Überblick über die Datenhaltung in Anwendungen Im Hinblick auf die Datenhaltung können in Anwendungen drei Schichten unterschieden werden: Zuunterst liegt die eigentliche Dateischicht - im Allgemeinen also die Ablage im Dateisystem des Rechners. Hier sind aber auch Netzwerkschnittstellen und Ähnliches möglich (tatsächlich werden etwa unter UNIX solche im Dateisystem als spezielle Dateien sicht- und nutzbar gemacht). Darüber folgt die Laufzeitspeicherschicht - wie also die Daten im Hauptspeicher abgelegt werden. Zuoberst dann Programmlogik und Anzeige, welche die Daten nutzt. Alle drei Schichten stehen dabei in Interaktion miteinander. Wie im Schema bereits angedeutet, stehen die beiden unteren Schichten in einer engen Beziehung. 13 KAPITEL 2. NUTZEN MEDIZINISCHER DIALOGSYSTEME Bezeichner im Anamnesebaum mit dem Schlüssel a$1221 bedeutet so viel wie nimm am Wurzelknoten den 1. Zweig, danach den 2., danach nocheinmal den zweiten und in Tiefe vier wieder den 1. Zweig. Die einzelnen Tiefen entsprechen verschiedenen Kriterien, etwa zur Lokalisation von Schmerzen (Kopf, Beine, ...), zeitliches Auftreten und so weiter. Damit sind also sehr spezielle Konzepte darstellbar. Um Generalisieren zu können, werden nun auch Platzhalter zugelassen, d.h. man kann eine Menge von Konzepten etwa mit a$1xx1 zusammenfassen. Damit können etwa Kopfschmerzen am Auge zusammengefasst werden, die sowohl rechts- als auch linksseitig auftreten. Diese Strukturen sind vorerst statisch. Sie werden zum Bearbeiten in Lisp-ähnlichen Dateien gespeichert. Bei der Installation werden die Definitionen dann auf eine Datenbank übertragen, um so für alle Clients verfügbar gemacht zu werden. Eine andere Art Daten sind die von den Patienten erhobenen. Das betrifft zum Einen Antworten aus Dialogen, aber auch Diagnosen und Therapien, die dann angewandt wurden. Diese Daten referenzieren über semantische Schlüssel Knoten in den Wissensbäumen. Es handelt sich hier um eher episodisches Wissen, dass durch jede Praxis separat erhoben wird und daher dynamisch ist. Das große Ziel der iSuite ist es nun, sowohl die statischen Konzepte, als auch die dynamisch erhobenen Episoden zu nutzen, um so Wissen abzuleiten und den Arzt bei seiner Arbeit zu unterstützen, indem etwa Medikationen vorgeschlagen werden oder alternative Behandlungen angezeigt werden können. Um Parallelen etwa zu Beschreibungslogiken zu ziehen, könnte man die statischen Daten als TBox (also generelles Wissen oder eine Regelbasis) und die dynamischen als ABox (Einzel- oder Fallwissen) bezeichnen. Aus softwaretechnischer Sicht ergeben sich nun folgende Schwerpunkte: • Die Daten der TBox sollten zur Bearbeitung in einem möglichst einfachen Format gehalten werden, so dass es etwa auch möglich ist, Fachexperten aus dem Bereich Medizin heranzuziehen, um sie zu editieren. • Zusammenhänge zwischen TBox und ABox. Die Episoden müssen sich irgendwie auf Konzepte abbilden lassen, so dass programmatisch Wissen abgeleitet werden kann. • Bearbeiten der Wissensbasis. Wenn Änderungen an der Wissensbasis vorgenommen werden, zieht das auch Änderungen an den Episoden nach sich, da dann die Schlüssel, die zum Verweis auf Konzepte benötigt werden, unter Umständen 14 KAPITEL 2. NUTZEN MEDIZINISCHER DIALOGSYSTEME ungültig werden. Das ist vor allem bei Updates bestehender Installationen der iSuite wichtig. 15 3. Speicherformate und Datenhaltung Das folgende Kapitel ist im Grunde noch einmal zweigeteilt: Betrachtet man Applikationen in Hinblick auf ihre Daten, dann macht es Sinn, eine Unterteilung zwischen der Art und Weise, wie diese abgespeichert werden (ergo den Dateiformaten) auf der einen und wie schließlich die Repräsentation im Speicher erfolgt auf der anderen Seite zu machen. Beide Seiten können dabei durchaus in enger Wechselwirkung stehen: Ein verwendetes Dateiformat kann eine Entscheidung bzgl. der Abspeicherung bevorzugen. Auf der anderen Seite kann die geplante Art der Datenhaltung während der Ausführung des Programmes auch bestimmte Dateiformate als erste Wahl erscheinen lassen. Folgt man diesem Ansatz kommt man schließlich zu einer Designphilosophie, die wenig oder gar keine Arbeit bevorzugt und stattdessen auf vorhandene Bibliotheken und Mechanismen zum Laden und Speichern setzt. Ein anderer Ansatz kann die totale Trennung der Speicherung auf einem permanenten Datenträger und im Arbeitsspeicher sein. Auch diese Sicht ist berechtigt, erlaubt sie im Nachhinein in der Regel ein problemloses bzw. -armes Austauschen der ein oder anderen Komponente. Diesem Weg folgend muss dem Design sehr viel mehr Beachtung geschenkt und gleichfalls auch insgesamt mehr Arbeit in Kauf genommen werden. Die dafür erhaltenen Resultate allerdings gleichen diesen Mehraufwand (zumindest wo es sinnvoll ist1 ) wieder aus. Im Folgenden sollen nun zuerst einige Dateiformate betrachtet werden. Vor- und Nachteile der Formate sollen beschrieben und gegeneinander aufgewogen werden. Insbesondere sollen auch Anregungen gegeben werden, in welchen Umgebungen welches Format Sinn macht. Es ist anzumerken, dass die in diesem Abschnitt beschriebenen Aussagen nicht nur auf das Speichern im Dateisystem zutreffen, sondern beispielsweise auch auf den Austausch von Daten über eine Netzwerkschnittstelle. 1 Es sei darauf verwiesen, dass bei der Entscheidung, welcher Weg für eine Anwendung gegangen werden soll, ein gewisses Augenmaß erforderlich ist. Insbesondere bei sehr kleinen Anwendungen oder Applikationen mit eng begrenzten Anforderungen macht eine zu starke Abstraktion meist keinen Sinn, da der Aufwand – im Vergleich zur Gesamtentwicklungszeit – schlicht zu hoch ist 16 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG Allerdings soll der Fokus hier vorerst auf Ersterem liegen. Im Zweiten Teil soll dann eher auf die Speicherung der Daten im Hauptspeicher bzw. allgemeiner zur Laufzeit der Anwendung eingegangen werden. 3.1. Das perfekte Dateiformat? Der Titel dieses Abschnitts ist gleichsam die erste Frage, der sich dieses Kapitel widmen soll – wenngleich es auch eine sehr ketzerische Frage ist. In der Tat werden Diskussionen zu dem richtigen Dateiformat teils sehr hitzig und persönlich geführt. Tatsächlich legen sich viele Entwickler von Software irgendwann auf ein bevorzugtes Format fest, welches sie dann auch mit allem Eifer verteidigen (hier sind interessante Parallelen zum Phänomen der sogenannten Self-Brand-Connections [6] erkennbar). Dabei ist die grundsätzliche Idee nicht gänzlich zu verwerfen: Wer sich auf ein Format festlegt, wird dieses im Laufe der Zeit mehr oder minder meistern. Im übrigen lohnt es auch, eine (z.B. firmeninterne) Bibliothek an Funktionen zur Interaktion mit dem ausgewählten Format anzulegen, die dann im Laufe der Zeit sehr mächtig werden kann und bei der Entwicklung neuer Anwendungen einen nicht unerheblichen Teil der Arbeit quasi von selbst übernimmt. Wer hingegen für jedes Projekt neu wählt, wird nicht selten im Nachhinein feststellen, dass etwaige Vorteile des genutzen Dateiformates nicht ausgereizt oder möglicherweise gar nicht genutzt wurden. Leider – das werden auch die folgenden Abschnitte zeigen – gibt es so ein Format nicht. Es mag gewisse Tendenzen hin zu einigen geben (etwa weil die Werkzeugunterstützung sehr gut ist oder es gerade einfach nur gehyped wird), aber in aller Regel sollten Anwendungsentwickler in der Analysephase des Projektes die Anforderungen an das Programm sorgfältig untersuchen, um anhand dieser ein möglichst passendes Dateiformat auszuwählen. 3.2. Vergleich gängiger Formate Im Folgenden sollen nun einige bekannte und oft verwendete Formate sowie Lösungen vorgestellt werden. Dabei werden einige konkrete Formate betrachtet, aber auch einige eher allgemeine Lösungen analysiert. 17 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG 3.2.1. Binärdateien Binärdateien bzw. -formate sind solche, bei denen beim Schreiben auf persistenten Speicher keine Umwandlung der internen Strukturen in ein textuelles (vom Menschen lesbares) Format erfolgt. Im Idealfall sind solche Formate also eine Art Dump, d.h. eine Abbildung der Daten im Speicher. Das stellt auch gleich den größten Vorteil dieser Formate dar: Es werden weder komplizierte Aus- noch Eingaberoutinen benötigt. Gerade zweitere können das Laden von Daten recht zeitintensiv machen. Ein weiterer Vorteil ist die Speicherplatzeffizienz: Wenn etwa zur Darstellung einer Zahl im Speicher 4 Byte veranschlagt werden, so bleibt dieser Wert auch beim Schreiben in den Sekundärspeicher konstant. Dennoch gibt es auch einige Dinge, die bei solchen Formaten beachtet werden sollten. Ein beliebter Fehler ist es etwa, Zeiger im Speicher as-is“ zu schreiben. Das er” gibt natürlich keinen Sinn, denn nach dem erneuten Laden ist das Objekt, auf das gezeigt wurde, in der Regel an einer anderen Addresse im Speicher zu finden. Solche Fehler schleichen sich oft ein, wenn vom Compiler angebotene Referenztypen wie einfache Datentypen behandelt werden (zum Beispiel der Typ string in Delphi bzw. Object Pascal). Ein weiteres Problem kann das sogenannte Byte Ordering sein. Dieses Problem tritt dort auf, wo Datentypen (in der Regel Ganzzahlwerte, die direkt von der CPU verarbeitet werden) aus mehreren Speicherzellen zusammengesetzt sind. So werden auf gängigen Consumer Systemen etwa 32 Bit Zahlwerte aus 4 einzelnen Bytes (der kleinsten addressierbaren Speichereinheit) dargestellt. Diese 4 Byte liegen – beginnend ab einer Adresse – direkt hintereinander im Speicher. Es haben sich im Laufe der Zeit zwei Wege etabliert, wie diese Darstellung erfolgen kann. Als Beispiel soll die Hexadezimalzahl 0xAABBCCDD dienen. Bei der Verwendung des Big Endian Formates liegt beginnend bei der Startaddresse (oder Offset) das Höchstwertige Byte (also das Byte mit dem Wert 0xAA), dann folgt das Byte mit dem zweithöchsten Wert (0xBB) und so weiter. Die Darstellung im Little Endian Format hingegen ist genau umgekehrt, das heißt am Offset wird der Wert 0xDD gelesen, danach 0xCC und so weiter. Das Problem der Bytereihenfolge stellt sich immer dann, wenn verschiedene Systemarchitekturen zusammenarbeiten; besonders häufig also bei der Kommunikation über ein Netzwerk. Daher ist es in diesem Bereich auch üblich, die Daten vor dem Versenden über ein Netzwerksocket zu konvertieren. Aber auch bei der Speicherung im Sekundärspeicher muss die Bytereihenfolge beachtet werden, wenn nämlich mehr als eine Zielarchitektur angepeilt wird. Dabei gibt es verschiedene Lösungsmöglich- 18 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG keiten: Die einfachste ist, bei der Spezifikation des Dateiformates eine Bytereihenfolge festzuschreiben. Wenn die Anwendung also auf einer Architektur läuft, die die selbe Bytereihenfolge verwendet wie das Dateiformat, können betroffene Datentypen direkt geschrieben (und gelesen) werden. Wenn sich allerdings das Byte Ordering der Architektur von der des Formates unterscheidet, müssen die Daten beim Lesen und Schreiben konvertiert werden. Dieses Vorgehen hat einen offensichtlichen Nachteil: Während man auf einem Teil der Architekturen stets ohne Konvertierung (und damit auch ohne Performanceeinbußen) auskommt, muss auf dem anderen Teil stets konvertiert werden. Eine elegantere Lösung ist es daher, die Bytereihenfolge nicht in der Formatspezifikation festzusetzen, sondern stattdessen direkt in jeder Datei zu vermerken, welche Bytereihenfolge verwendet wird. Ein solches Vorgehen wird etwa beim PCAP Dateiformat verwendet [20]: Ganz an den Anfang der Datei wird dabei ein magic value, 0xA1B2C3D4 geschrieben – und zwar in der nativen Bytereihenfolge der Architektur. Der Rest der Datei wird ebenfalls in der nativen Bytereihenfolge geschrieben. Damit erfolgt das Schreiben – egal auf welcher Architektur – stets ohne Overhead. Beim Lesen wird nun wie folgt vorgegangen: Das Programm ließt den Wert am Anfang der Datei in seiner nativen Bytereihenfolge ein. Wenn es dann den Wert 0xA1B2C3D4 sieht, stet fest, dass die Datei mit dem selben Byte Ordering geschrieben wurde, den auch die aktuelle Architektur verwendet – der Rest der Datei kann also ebenfalls ohne Overhead durch Konvertierungen eingelesen werden. Wenn allerdings der Wert 0xD4C3B2A1 gelesen wurde, dann muss beim Rest der Datei konvertiert werden, da das Schreiben mit genau der anderen Reihenfolge erfolgt ist. Ergo: Das Lesen erfolgt nur mit Performanceeinbußen, wenn Dateien einer anderen Architektur importiert“ werden; solange also kein direkter Austausch zwischen ” verschiedenen Architekturen erfolgt, existiert überhaupt kein Overhead. Ein Nachteil von Binärformaten lässt sich allerdings nicht ausgleichen: Sie sind für den Menschen nicht (oder nur schwer) les- und interpretierbar. So lassen sich solche Dateien nicht in einem normalen Texteditor öffnen (bzw. stellen die meisten Texteditoren in diesem Fall nur Zeichensalat dar). Zwar gibt es spezielle Binäreditoren (z.B. Okteta, siehe 3.1), allerdings erhält man auch mit diesen nur eine Darstellen in Tabellen- oder Listenform mit einigen Tools um die Daten aufzubereiten und verschiedene Interpretationen einer Bytefolge anzuzeigen. Eine Semantik im Strom der Bytes zu erkennen liegt am jeweiligen Betrachter. Natürlich kann dieser Nachteil in einigen Fällen eher marginal sein. Sobald man allerdings an den Punkt kommt, an dem man die eigentlichen Dateien betrachten muss (etwa, wenn Fehler auftreten und 19 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG man die Applikation debuggen muss), kann die Verwendung von Binärdateien nachteilig sein. 3.2.2. Proprietäre Textformate Proprietär meint in diesem Fall nicht standardisierte Formate. Textformate gleichen einen großen Nachteil der Binärformate aus: Sie können vom Menschen leicht untersucht werden (es eignet sich im Prinzip jeder Texteditor) und in vielen Fällen erschließt sich die Semantik recht schnell, oft auch ohne vorherige Lektüre zugehöriger Spezifikationen. Ebenfalls stellt sich das Problem des Byte Ordering nicht, denn die textuelle Darstellung von Zahlen ist (in der Regel) von der Bytereihenfolge unabhängig. Dafür entfällt der Vorteil der Schnelligkeit: Die Daten müssen jeweils beim Lesen und Schreiben konvertiert werden, was nicht unerheblich viel Zeit kosten kann. Insbesondere das Lesen kann – je nach gewähltem Aufbau der Dateien – viel Zeit veranschlagen. Aus diesem Grund sollte man in Situationen, wo das Lesen und Schreiben zeitkritisch ist, wohl eher auf Binärformate zurückgreifen. Ein weiterer Punkt: Die textuelle Darstellung ist um ein Vielfaches größer, als die binäre Darstellung. Gerade in heutiger Zeit (anno 2011 sind Festplatten von 500 GByte und mehr nicht unüblich) macht das scheinbar wenig aus. Kritisch wird es hingegen, wenn die Dateien dafür bestimmt sind, via Netzwerk verschickt zu werden (etwa, wenn ein HTTP Server die Dateien on-the-fly generiert und Clients diese herunterladen). Um die Downloadzeiten möglichst gering zu halten, ist es ratsam, kompakte Speicherformate zu wählen. Binärformate haben dieses Problem nicht. Eine Alternative wäre, die Textdateien nach dem Generieren zu komprimieren. Das macht allerdings nur Sinn, wenn zwar die Übertragungskanäle eher schmal sind, dafür die erwarteten Server und Clients sehr leistungsstark (also das Komprimieren und Auspacken weniger Zeit in Anspruch nimmt, als der direkte Download der größeren, ungepackten Dateien. 3.2.3. Extensible Markup Language Die Extensible Markup Language – oder kurz XML – ist prinzipiell nur ein spezielles Textformat. Das impliziert sofort alle Vor- und Nachteile allgemeiner textbasierter Formate. In der Tat aber hat XML einige Eigenschaften, die es Wert machen, dieses Format genauer zu betrachten. 20 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG Abbildung 3.1.: Binäreditor Okteta“ ” Binäreditoren wie Okteta erlauben das Editieren von Binärdateien (im Beispiel etwa eine PDF Datei). Allerdings ist auch mit den angebotenen Werkzeugen ein Arbeiten nicht ganz einfach - sie helfen zwar durchaus bei der Analyse, dennoch ist es nicht einfach, in der Folge von Bytes Muster zu erkennen (insbesondere, wenn das Binärformat keine oder kaum Zeichenketten enthält, sondern vorwiegend numerische Werte). 21 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG So gibt es in fast allen gängigen Entwicklungsumgebungen bereits fertige Lösungen, um XML zu laden und zu schreiben. Wenn also die zu entwickelnde Applikation ohnehin nach dem Baukastenprinzip geschrieben werden soll, sollte geprüft werden, ob XML als Speicherformat in Frage kommt; da die Ein- und Ausgaberoutinen dafür teilweise über Jahre entwickelt wurden, sind sie in der Regel vergleichsweise schnell und vor allem gut getestet. Es ist also allemal besser, diese zu nutzen, statt selbst ein eigenes Format zu entwickeln und dabei Gefahr zu laufen, ein unperformantes und fehleranfälliges E/A Framework zu bauen. Davon abgesehen hat XML aber noch weitere, interessante Eigenschaften. Standardisierung Eine sehr wichtige Eigenschaft von XML ist, dass es standardisiert ist: So existiert eine sogenannte Recommendation des W3C [5], in der etwa die Syntax von XML festgehalten ist. Das hat nicht unerhebliche Konsequenzen: Gängige Ein- und Ausgaberoutinen, die sich an diese Empfehlung halten, sind untereinander kompatibel – eine XML Datei, die also mit einer Applikation geschrieben wurde, kann in der Regel problemlos mit einer anderen Anwendung geladen werden. Das ist unter Anderem in sehr großen Projekten von Vorteil, wo aus gegebenen Gründen meist nicht nur eine Programmiersprache bzw. Laufzeitumgebung genutzt wird, sondern in der Regel eine Ansammlung vieler verschiedener Komponenten – angefangen bei verschiedenen Compilern, über unterschiedliche Umgebungen zum Skripten bis hin zu mehreren Betriebssystemen. In solchen Umgebungen ist es essentiell, dass die Daten zwischen den Subapplikationen ausgetauscht werden können – was durch XML sehr gut unterstützt wird. Da die Syntax weiterhin festgeschrieben ist, ist es einfach, zumindest grundlegende Prüfungen, ob eine Datei wohlgeformt ist, durchzuführen. So sind in vielen Texteditoren (z.B. Kate) Funktionen enthalten, die das aktuelle Dokument auf well-formedness hin prüfen (siehe 3.2). Constraints XML selbst kann an und für sich als eine Festschreibung der allgemeinen Syntax eines Textformates betrachtet werden. Das bedeutet natürlich, das neben dem Parsen des eigentlichen XML im Programm noch das Extrahieren der Informationen erfolgen muss. Das Problem hierbei: Die entstehenden Quelltexte sind dadurch oft sehr unübersichtlich, da sehr viele Constraint Checks eingebaut sind (heißt das Wurzel- 22 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG Abbildung 3.2.: Texteditor Kate“ ” Viele fortgeschrittene Texteditoren, wie etwa Kate, bieten Funktionen, um XML Dateien auf Wohlgeformtheit hin zu prüfen. Ist in der Datei eine Referenz auf eine Definitionsdatei angegeben, wird sogar versucht, automatisch gegen diese zu prüfen – das erspart häufig ein Trial’n’Error Vorgehen beim Schreiben von Dateien: Anstatt diese erst zu schreiben und dann testweise das Programm zu starten, was sie nutzt – um damit die Validität zu prüfen – kann gleich alles aus dem Editor heraus gemacht werden. 23 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG element XYZ, sind direkt darunter nur Elemente A, B oder C, usw.) Das kann zwar – etwa durch Design Pattern wie Check-and-Return [2] – versuchsweise verbessert werden. Schöner ist allerdings eine andere Methode: Denn ebenfalls zu XML wurden Möglichkeiten definiert, um den Aufbau einer XML Datei genauer zu bestimmen und diverse Einschränkungen (englisch constraints) zu machen. Die verbreitetsten Möglichkeiten dazu sind die sogenannten Document Type Definitions (DTD) welche in der XML Recommendation beschrieben werden [5] sowie die XML Schema Definitions ([9], [21] und [4]). Beide können dazu genutzt werden um festzulegen, welche Elemente und Attribute in einem XML Dokument verwendet werden dürfen, wie oft und in welcher Abfolge das passieren kann und welche Datentypen in Attributen oder auch innerhalb von Elementen stehen dürfen. Ein XML kann dann eine DTD oder XSD Datei referenzieren. Wird ein sogenannter validierender Parser verwendet, so wird dieser – neben der Wohlgeformtheit der Datei – auch prüfen, ob die Datei den Beschränkungen der referenzierten Datei genügt. Der Vorteil liegt ganz klar auf der Hand: Im eigentlichen Programmcode muss nicht mehr (zumindest auf grundlegende) Dinge geprüft werden. Hat der Parser die Datei akzeptiert, kann man sicher sein, dass die Struktur den geforderten Spezifikationen genügt. Semantische Zusammenhänge müssen zwar dennoch unter Umständen geprüft werden (z.B. ob Identifikatoren innerhalb des Dokumentes einmalig sind), trotzdem ist die Reduzierung des Prüfcodes innerhalb der Applikation hilfreich, da so eine bessere Übersicht gewahrt wird. Abfrage- und Transformationssprachen Oftmals benötigt man nicht den kompletten Datenbestand, der in einer Datei abgespeichert ist. Prinzipiell ist die Situation vergleichbar mit einer Datenbank: Die Datenbank nimmt eine potentiell sehr große Menge an Daten auf; zu einem einzigen Zeitpunkt allerdings ist man in der Regel aber nur an einer kleinen Untermenge der Fakten interessiert. Nun kann natürlich versucht werden, jeweils die Daten, die benötigt werden, per Hand“ im Programm aus dem Datenbestand herauszufiltern ” (etwa, indem das gesamte XML geladen wird und dann über die Dokumentstruktur traversiert wird). Allerdings wird dies oft zu Dopplungen im Quelltext führen. Grund ist, dass – zumindest in den meisten objektorientierten/imperativen Sprachen – im Quelltext hinterlegt ist, wie etwas gemacht wird (also das Suchen in der Baumstruktur und filtern der Daten). Interessiert ist man aber eigentlich nur daran, was gesucht wird. Auch hierfür gibt es vom W3C bereits fertige Lösungen: Die XML Query Langua- 24 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG ge oder XPath (aktuell werden sowohl die Version 1 [7] als auch die Nachfolgeversion 2 [3] verwendet). XPath gehört damit – wie auch auch ein Teil von SQL – zu den Data Query Languages, die ausschließlich darauf ausgelegt sind, Teilinformationen aus einem System abzufragen. Es sei aber angemerkt, dass SQL noch weitere Aufgaben umfasst (so dient es in aktuellen Datenbanksystemen etwa auch als Data Definition Language und Data Manipulation Language [16]. XPath hingegen ist eine reine Abfragesprache. Allerdings gibt es – aufbauend auf XPath – auch weitere Möglichkeiten. So kann man beispielsweise XSL Transformation (kurz XSLT) verwenden, um ein XML Dokument in einem XML Dialekt in einen anderen Dialekt oder aber auch in eine komplett andere Form (etwa das Rich Text Format) zu überführen [13]. Auch hier gilt wieder: Man beschreibt nicht, wie man die Daten überführt, sondern welche Eingangsdaten in welche Ausgangsdaten zu überführen sind; da auch dies wieder in separaten Dateien geschieht, werden Quelltexte deutlich übersichtlicher (so benötigt man ein in einer Hochsprache geschriebenes Programm dann teilweise etwa nur noch als Shell, um die Umwandlung via einer Standardbibliothek zur Transformation von XML anzustoßen (und sogar das lässt sich umgehen, da es bereits fertige Programme gibt, die eine XML und eine XSLT Datei als Eingabe entgegennehmen und die entsprechenden transformierten Ergebnisse ausgibt, etwa xsltproc2 ). 3.2.4. Datenbanken Datenbanken sind im eigentlichen Sinne nicht als Dateiformat zu verstehen. Zwar werden die Daten auch hier in den Sekundärspeicher geschrieben – allerdings wird der Aufbau der eigentlichen Dateien stets hinter einer API versteckt bzw. läuft der Datenbankserver oft auch auf einem anderen Rechner als die Clientapplikation (die Anwendung kann also nicht einmal sicher sein, dass in den lokalen Sekundärspeicher geschrieben wird). Aus Sicht eines Anwendungsentwicklers hingegen kann ein Datenbanksystem durchaus als spezielles, virtuelles Dateisystem aufgefasst werden, bei dem der Zugriff auf die Dateien nicht über das vom Betriebssystem angebotene File Interface erfolgt, sondern über eine spezielle API. Die Nutzung von Datenbanksystemen als Speicher sollte wohlüberlegt sein. Die sich ergebende Struktur kann durchaus sehr nützlich und flexibel sein, allerdings gibt es definitiv Einschränkungen, die zu beachten sind. 2 http://xmlsoft.org/XSLT/xsltproc2.html 25 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG Viele bestehende Systeme sind darauf ausgelegt, im Laufe der Zeit sehr große Datenbestände inkrementell aufzunehmen. Gleichsam wird eine Schnittstelle angeboten, mit der Teile der Informationen abgerufen werden können. Wenn also die zu entwickelnde Anwendung dieses Nutzungsschema bedient, sind Datenbanken zur Datenablage durchaus gut geeignet. Vor allem das Suchen in (potentiell sehr großen) Datenbeständen wird dadurch gut unterstützt. Problematisch wird es hingegen, wenn große Datenbestände auf einmal abgefragt werden sollten (z.B. der gesamte Datenbankinhalt soll in den Primärspeicher des Client übertragen werden, weil dieser dort Berechnungen über den Daten durchführen muss). In einem solchen Szenario können sich Datenbanken durchaus als Flaschenhals erweisen, die die Gesamtperformance eher vermindern [12]. Auch muss das angepeilte Objektmodell passen. Datenbanken eignen sich dort als Speicher, wo es sehr viele Objekte des gleichen Typs gibt. In einer Hochsprache wie z.B. C++ oder C# wird dies oft der Fall sein (es existieren eine vergleichsweise kleine Zahl verschiedener Klassen, von denen zur Laufzeit potentiell sehr viele Instanzen gebildet werden). Anders hingegen kann es in dynamischen Sprachen aussehen. Als Beispiel ist hier etwa JavaScript bzw. ECMA Script zu nennen: Dort ist eine Klasse prinzipiell eine Map, d.h. es werden Eigenschaftsnamen auf konkrete Werte abgebildet. Zwar gibt es auch dort Klassen, allerdings beschränkt das nicht die Eigenschaften, die ein Objekt zur Laufzeit haben kann (die Instantiierung erfolgt prototypenbasiert, d.h. die Instanz ist eine Kopie eines Prototypen, der – neben dem initialen Aussehen des Objektes – keine weiteren Vorgaben macht). In einer Umgebung, in der dies ausgenutzt wird, kann es unter Umständen sehr schwierig sein, die Objekte zur Laufzeit auf ein Datenbankschema abzubilden. Hier wäre die Abbildung z.B. in eine XML Datei ohne Schema bzw. DTD einfacher; besser sogar noch die Verwendung von JSON [8]. 3.2.5. Ausblick Man könnte an dieser Stelle noch fortfahren, weitere konkrete Formate zur Speicherung aufzuzählen. Viele dieser Möglichkeiten lassen sich in der Tat aber auf die bereits vorgestellten zurückführen, womit sich ähnliche Vor- und Nachteile der Verwendung sofort ableiten. Stattdessen sei hier nur kurz auf einige Entwicklungen und Möglichkeiten verwiesen. 26 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG Skriptsprachen als Dateiformat Skriptsprachen selbst eignen sich unter Umständen ebenfalls sehr gut als Speicherformat – beispielsweise Lua [11]; besonders dann, wenn auch die Applikation selbst ganz oder teilweise (z.B. durch einen eingebetteten Interpreter) in dieser Sprache geschrieben ist. In diesem Fall können die Dateien, welche Wissensbestände enthalten, direkt (zusammen mit den Dateien, in denen die Anwendungslogik implementiert ist) geladen werden. Bei Lua kommt zusätzlich hinzu, dass nach außen hin eine einfache API zur Verfügung gestellt wird, mit der auf die Daten zugegriffen werden kann (daher ist diese Sprache auch in einem sonst reinen C oder C++ Programm hervorragend als Datenspeicher zu gebrauchen). Google Protocol Buffers Die Google Protocol Buffers sind eine interessante Neuentwicklung von Google, die vor allem in großen Rechnernetzen nützlich sind. Von der Website des Projektes [10]: Protocol buffers are Google’s language-neutral, platform-neutral, extensible ” mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages – Java, C++, or Python.“ Die Idee ist, dass die Struktur der Daten (ähnlich DTDs oder XSDs) definiert wird. Quelltexte zum Laden und Schreiben werden automatisch aus diesen Definitionen generiert. So können die Informationen etwa als XML oder JSON Dateien gespeichert werden. Das Besondere: Die Ablage der Daten erfolgt spaltenweise [15]. Wie bei SQL und Datenbanksystemen muss also nicht der gesamte Informationsbestand abgefragt werden, wenn man z.B. für eine Berechnung nur wenige Werte pro Objekt benötigt. 3.2.6. Zusammenfassung Dieser Abschnitt hat versucht, das Thema Dateiformate etwas zu beleuchten. Dabei wurden teils sehr allgemeine Formate bzw. Möglichkeiten betrachtet (binär vs. textbasiert), aber auch einige konkrete vorgestellt (XML). Es wurde versucht, in den einzelnen Unterabschnitten die jeweiligen Vor- und Nachteile aufzuzeigen und bereits Hin- 27 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG weise gegeben, in welchen Szenarien welche Formate geeignet sind. Grundsätzlich sind dabei • Geschwindigkeit beim Laden und Schreiben • Speicherverbrauch • Les- und damit Untersuchbarkeit • Unterstützung durch vorhandene Werkzeuge und Frameworks wichtige Kritikpunkte, anhand derer die Entscheidung für eines der Formate gefällt werden sollte. Besonders dem letzten Punkt sollte besondere Aufmerksamkeit geschenkt werden, da bestehende Routinen teilweise recht alt und damit ausgereift sind, was in der Regel eine gute Performance verspricht sowie die Entwicklungszeit für Applikationen (im Vergleich zu Eigenentwicklungen) deutlich verringert. Ein Format, welches in allen Punkten Vorteile hat gibt es nicht – so muss also für jedes Projekt, je nach zu erwartenden Use Cases, entschieden werden. 3.3. Organisation der Datenhaltung in Anwendungen Während der vorhergehende Abschnitt den Dateiformaten gewidmet war – also der Art und Weise, wie Daten und Wissen einer Anwendung im Sekundärspeicher abgelegt werden können – soll dieser Abschnitt nun das Thema Datenhaltung zur Laufzeit (also im Primärspeicher des Rechners) genauer untersuchen. Wie Eingangs bereits kurz erwähnt, können dabei zwei grundsätzliche Herangehensweisen unterschieden werden. 3.3.1. Direkter Zugriff auf Dateien Gerade wenn die Entscheidung hin zu einem bekannten“ Dateiformat gefallen ist – ” etwa XML – kann es durchaus Sinn machen, vorhandene Komponenten zum Laden und Speichern auch gleich weiterzuverwenden“. So gibt es in der Regel (zumindest ” in objektorientierten Sprachen) Klassen, mit denen ein komplettes XML Dokument auf einmal in den Speicher geladen wird und dann als eine Art Datenbank behandelt werden kann, an die – etwa mit XPath oder via XSLT Skripten – Anfragen gestellt werden können. 28 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG Binär Sehr hoch Text XML Mittel bis gering, je nach Aufbau des konkreten Formates DBS GeSchnell bei schwinkleinen digkeit Anfragen, langsam bei Anforderung großer Datenmengen Debugging Schwierig, Sehr einfach, keine speziJe nach vererfordert ellen Dateibetrachter notwendeter spezielle Da- wendig Datenbank, teibetrachter in der Regel und viel aber nur zur Vorwissen Laufzeit via Debugger Unterstüt- In der Regel pro AnwenSehr gu- Je nach DBS zung zur dung eigene proprietäre te Un- und EntProgramFormate, daher oft keine terstützung wicklungsmierung vorhandenen SDKs nutzin einer umgebung bar Vielzahl unterschiedvorhandener liche UnEntwickterstützung lungsumgebzw. Anbungen bindung vorhanden Tabelle 3.1.: Vergleich ausgewählter Dateiformate und Vorgehen 29 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG Wenn also eine möglichst kurze Entwicklungszeit im Vordergrund steht, kann ohne Weiteres diese vorhandene Funktionalität genutzt werden. 3.3.2. Abstrahierter Zugriff Eine andere Herangehensweise ist es, den Zugriff auf die Dateischicht komplett zu abstrahieren. So würde eine komplette zusätzliche Schicht zwischen der eigentlichen Anwendungslogik und den eigentlichen Daten im Sekundärspeicher eingezogen, die prinzipiell nur zu Lade- und Speicherzwecken dient und weitere low level Aufgaben übernimmt. Die Implementation einer guten Abstraktion ist dabei mitunter recht zeitaufwändig. Dafür zahlt sich diese Arbeit aber aus, wenn im Laufe der Zeit neue Anforderungen an die Anwendung gestellt werden, denn die Umstellung des Dateiformates selbst ließe dann die Anwendungslogik unangetastet. Mehr noch: Man könnte mehrere Dateiformate unterstützten, ohne, dass dies zu viel Aufwand bedeutet – es werden lediglich neue Ein- und Ausgaberoutinen benötigt. 3.3.3. Die Repository-Metapher Allgemein kann man den Datenbestand einer Anwendung als ein Repositorium – oder englisch repository – auffassen: Also einen Speicher von Daten. Unterteilt man eine Anwendung (oder allgemeint auch andere Arten von Software, etwa Frameworks) in unterschiedliche Schichten, so liegt zuunterst meist eine Schicht, die dieses Repository zur Verfügung stellt. Die beschriebenen Zugriffsweisen führen dann zu verschiedenen Arten solcher Repositorien, die sich hinsichtlich ihrer Schnittstellen zu den darüber liegenden Anwendungsschichten unterscheiden. Zum Vergleich kann hier [1] herangezogen werden; es sei angemerkt, dass sich diese Quelle mit dem Thema Software-Entwicklungswerkzeugen befasst. Allerdings sind die Intentionen durchaus vergleichbar. White Box Repository Bei einem White Box Repository haben höhere Schichten vollen Zugriff auf die Interna des Repository, siehe 3.3. Hier passt der oben genannte Fall der Verwendung von XML und der direkten Nutzung der geparsten Daten via Standardbibliotheken. Ein weiteres Beispiel wäre die Verwendung von Datenbanken und damit verbunden 30 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG App 1 App 2 App N Ein-/Ausgabe Ein-/Ausgabe Ein-/Ausgabe Daten Abbildung 3.3.: White Box Repository Bei einem White Box Repository erfolgt der Zugriff auf die Daten direkt“, d.h. die Komponenten, die das ” eigentliche Laden und Speichern übernehmen, werden gleich weiterverwendet. Bei einer Applikation, die aus mehreren Einzelanwendungen besteht, implementiert damit typischerweise jede dieser Anwendungen die Ein- und Ausgabe selbst. der Möglichkeit, etwa SQL Anfragen gegen diese abzusetzen. Der Vorteil ist stets, dass vorhandene APIs und Schnittstellen ohne Umwege genutzt werden können, was ein Ersparnis bei der Enwicklungszeit einbringt und – was ebenfalls von Vorteil sein kann – die oberen Anwendungsschichten haben vollen Zugriff auf alle Features der genutzen Speicherformate. Allerdings werden dann gleichsam alle Anwendungsschichten an diese Formate gebunden; ein Austauschen hätte zur Folge, dass Änderungen u.U. an sehr vielen Stellen im Quelltext vorgenommen werden müssen. Black Box Repository Strebt man hingegen eine möglichst große Abstraktion an, kommt man zu Black Box Repositories. Diese haben meist eine feste Schnittstelle nach oben hin, gegen die weitere Anwendungsschichten programmiert werden (siehe 3.4). Das legt auch gleich ihren großen Vorteil dar: Die verwendeten Dateiformate spielen eigentlich keine Rolle mehr – man kann sie später ohne weiteres austauschen (etwa, wenn andere Formate eine bessere Performance beim Laden/Speichern versprechen). Auch kann man 31 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG damit einen sehr flexiblen Zugriff auf alternative Speicher erlauben: So könnten entfernte Dateien beispielsweise über Protokolle wie SSH, FTP oder HTTP verfügbar gemacht werden. Als ein sehr ausgereiftes Framework können hier die KIO Slaves des KDE Projektes genannt werden [14]. Diese werden bei vielen Programmen des KDE Desktops verwendet, die Dateiein- und ausgabe benötigen. Statt also die Dateien selbst, etwa mit den Funktionen der Standard C/C++ Bibliothek, anzusprechen, werden sogenannte KIO ( KDE Input/Output“) Slaves verwendet. Damit ist es ei” nem Programm, welches diese nutzt, vollkommen egal, ob eine Datei im lokalen System liegt, oder über FTP, SSH oder andere Protokolle erst heruntergeladen werden muss. Des weiteren können im Nachhinein noch weitere dieser Slaves installiert werden, die dann sofort allen Programmen zur Verfügung stehen. Der Nachteil dieser Repositorien ist, dass zu Beginn eine längere Entwicklungszeit unbedingt eingeplant werden muss. Vor allem sollte auch das Design der Interfaces zu den oberen Schichten der Anwendung hin wohlkonzipiert sein, da eine spätere Anpassung – natürlich – wieder Änderungen am gesamten Quelltext der Applikation nach sich ziehen würde. Ebenfalls beachtet werden sollte, dass es nicht immer möglich ist, den vollen Funktionsumfang, den ein Speicherbackend bietet, nach oben hin durchzureichen (weil andere Speicherformate diese Funktion etwa nicht unterstützen und eine Emulation nur sehr schwer oder schlicht nicht möglich ist). Gray Box Repository Zwischenstufen zwischen White und Black Box Repository kann man auch als Gray Box bezeichnen. Bei diesen wird zwar auch eine einigermaßen starke Abstraktion der eigentlichen Datenhaltung vom Zugriff angestrebt, allerdings eben nicht vollständig. Hier könnte man sich etwa ein Repositorium vorstellen, welches den Zugriff auf verschiedene Datenbanksysteme kapselt (d.h. nach oben hin wird ein Interface angeboten, welches erst einmal den direkten Zugriff abschirmt und stattdessen z.B. Listen von Objekten anbietet, die dann intern die Datenbank abfragen, sobald auf die Felder der Objekte zugegriffen wird), aber auch die Möglichkeit einräumt, etwa SQL Anfragen gegen das gerade genutzte Datenbankbackend zu stellen. Das mag im ersten Moment zwar widersprüchlich erscheinen – wozu erst eine Abstraktion anstreben, wenn dann an einigen Stellen doch wieder gelockert und so eine Portabilität zunichte gemacht wird? – dennoch gibt es Use Cases, wo so ein Vorgehen Sinn macht. Wenn, um bei dem Beispiel zu bleiben, von Anfang an fest steht, dass als Speicherbackend irgendein relationales Datenbanksystem verwendet wird, dann kann man gewisse Funk- 32 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG App 1 App 2 App N Ein-/Ausgabe Ein-/Ausgabe Ein-/Ausgabe Daten Abbildung 3.4.: Black Box Repository Bei einem Black Box Repository wird zwischen den eigentlichen Daten und den Applikationen eine Schicht eingezogen. Diese übernimmt die Low Level Zugriffe auf die Dateien. Die Applikationen selbst sehen die Dateien nur durch den Repository Manager; damit ist das Format der Dateien – und sogar deren Speicherort – vollkommen egal. Änderungen und Erweiterungen müssen nur im Repository selbst vorgenommen werden; alle darauf aufbauenden Anwendungen können dann sofort und ohne Anpassung diese Erweiterungen nutzen. 33 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG tionen, die vielen oder allen diesen Systemen in der Regel gemein sind, auch nach außen hin zugreifbar machen. Abgeschirmt werden nur die Teile, die sich bei allen diesen Systemen unterscheiden – nämlich die konkrete API zum Ansprechen des jeweiligen Datenbankservers. Ein weiteres Beispiel: Es soll wieder XML genutzt werden, allerdings werden nach oben hin diesmal nicht die geladenen XML Dokumente zur Verfügung gestellt, sondern diese hinter einem eigenen Interface versteckt. Dieses Interface bietet nun auch Funktionen an, um via XPath Anfragen zu stellen und Informationen abzurufen. Das scheint vorerst natürlich an das XML Format zu binden. Allerdings könnte immer noch die konkrete Implementierung zum Laden der XML Dateien ausgetauscht werden – so könnte etwa ein DOM Parser gegen einen Stream Parser ausgetauscht werden, um die Belastung des Arbeitsspeichers zu verringern. Mehr noch: Der XPath Ausdruck selbst ist natürlich nicht an XML gebunden – vielmehr an die baumartige Graphenstruktur, die XML beschreibt. Daher kann der Ausdruck auch verwendet werden, um eine andere interne Datenstruktur abzufragen (die natürlich, ebenso wie XML, eine Baumstruktur aufweisen muss). Eine solche Funktionalität wird etwa durch die Qt4 Bibliothek bereitgestellt [18]. 3.3.4. Zentrale vs. Dezentrale Datenhaltung Ein weiterer Punkt bei der Datenhaltung ergibt sich, wenn eine Applikation nicht nur auf einem einzigen Rechner laufen soll, sondern vielmehr in einem Netz betrieben wird. In diesem Fall müssen die Daten meist geteilt werden. Es ist dann wichtig, dass gewisse Punkte eingehalten werden. Datenkonsistenz Wenn in einem System alle Clients nur lesenden Zugriff haben oder schreibender Zugriff durch eine einzelne Instanz geleitet wird, kann davon ausgegangen werden, dass die Daten stets konsistent sind (intuitiv ließt man stets, was man zuletzt geschrieben hat). Das folgt daraus, dass Änderungen an den Daten stets sequenziell erfolgen. Ein Setup, welches z.B. einen zentralen Datenbankserver zum Speichern nutzt, baut genau solch eine Architektur auf. Erlaubt man hingegen paralleles Schreiben, kann es dazu kommen, dass die Daten unkontrolliert überschrieben werden (A schreibt den Wert X in eine Datei, B kurze Zeit darauf den Wert Y, ohne dabei von der Änderung durch A etwas mitbekommen zu haben; ließt A nun sofort erneut, wird es einen – aus 34 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG seiner Sicht – falschen Wert lesen). Synchronisation Eine oft gewünschte Eigenschaft von Anwendungen ist, dass sie ihre Daten immer schreiben können. Das ist allerdings problematisch, wenn die Daten zentral etwa auf einem gemeinsamen Server abgelegt werden sollen. Wie sollte umgegangen werden, wenn der Client (zeitweise) offline ist und daher keine Verbindung zum Server aufbauen kann? Eine Möglichkeit ist, dass die Clients ihre Daten lokal speichern und dann eine Synchronisation untereinander oder über einen zentralen Server erfolgt. Dieses Modell verfolgen typische Version Control Systems (VCS) wie Subversion oder Git. Datenbaken zur Datenhaltung Werden Datenbanken zur Speicherung verwendet, gelangt man in der Regel zu zentralisierten Systemen. Da hier die Daten beim Schreiben durch einen einzigen Server geleitet werden, ist Konsistenz gewährleistet. Allerdings kann dieses Vorgehen in großen Netzen auch nachteilig sein, da der Datenbankserver einen Flaschenhals darstellt: Werden zu viele Anfragen auf einmal gestellt, bremst er die Clients aus, da sie auf die Beantwortung entsprechend lang warten müssen. Auch ist eine Datenbank nicht für alle Use Cases gut geeignet; etwa, wenn große Datenmengen auf einmal abgefragt werden müssen [15]. Version Control Systems zur Datenhaltung Eine Möglichkeit zur Nutzung von verteilten Speichern wäre die Verwendung von Version Control Systems (VCS) als Backend. Diese implementieren bereits die benötigten Synchronisationsroutinen, die zum Abgleich der Clients untereinander bzw. dem Server benötigt werden. Nachteilig ist hier, dass die Synchronisation nicht in jedem Fall konfliktfrei verläuft, in diesem Fall muss der Nutzer z.B. eine Version von zwei (oder mehr) möglichen auswählen. Ein Vorteil bei der Nutzung von VCS ergibt sich daraus, dass sie die Geschichte einer Datei behalten. Damit kann man jederzeit einen früheren Stand einer Datei wiederherstellen – oder im Kontext der Datenhaltung – stets auf ältere Versionen zugreifen. Das ist besonders dann von Vorteil, wenn die Dateien im System gleichermaßen 35 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG ihre Objekte im Speicher beschreiben. Ein Beispiel: In einem medizinischen Dialogsystem wird für jeden Patienten eine Datei mit seinen persönlichen Daten, sowie Anamnesen, Diagnosen, etc. angelegt. Anstatt neu gesammelte Informationen einfach nur an die Datei anzuhängen, überschreibt man (teilweise) bestehende. Zum Beispiel könnten stets nur die zuletzt gegebenen Antworten zu einem einzelnen Fragebogen abgespeichert werden. Im Dateisystem ist dabei standardmäßig nur die neueste Version der Datei sichtbar. Damit kann man mitunter normale Dateibetrachter oder – innerhalb der Anwendung vorhandene – Routinen zur Dateiein- und Ausgabe verwenden. Allerdings ist auch jederzeit eine ältere Version der Datei wiederherstellbar, wenn dies etwa zur detaillierten Betrachtung der Patientenhistorie notwendig ist. 3.3.5. Zusammenfassung Dieser Abschnitt hat sich mit der Frage beschäftigt, wie die Daten zur Laufzeit von Applikationen im Primärspeicher abgelegt werden bzw. wie der Zugriff auf die Dateien im Sekundärspeicher erfolgt. Dabei wurde das Repository als Metapher eingeführt. Je nach Zugriffsweise auf die zu Grunde liegenden Daten kann man drei Typen dieser unterscheiden: • Bei einem White Box Repository haben die einzelnen Applikationen vollen Zugriff auf die eigentlichen Dateien. Bei einer Applikation, die mehrere Unteranwendungen umfasst, implementiert dabei in der Regel jede dieser Anwendungen ihre Ein- und Ausgaben selbst. Diese Art Repository ist damit nur dort geeignet, wo von Anfang an ein Dateiformat festgeschrieben werden kann, da ein späterer Austausch weitreichende Änderungen nach sich zieht. Es ist aber auch dort einsetzbar, wo die Gesamtapplikation nur aus einer Anwendung besteht – in diesem Fall halten sich Änderungen im Nachhinein eher in Grenzen. • Bei einem Black Box Repository wird die Datenhaltung gegen darüberliegende Anwendungsschichten komplett abgeschirmt. Das erlaubt es, im Nachhinein die verwendeten Dateiformate auszutauschen oder zu ändern, ohne dass die Anwendungen, welche das Repository nutzen, angepasst werden müssen. Die Quelltexte der darüberliegenden Schichten müssen nur dann angefasst werden, wenn sich die Schnittstellen des Repository nach oben hin ändern – aus diesem Grund ist eine gewissenhafte Planung in der Analysephase des Projektes unabdingbar. Black Box Repository eignen sich vor allem in Anwendungen, die aus 36 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG mehreren Subapplikationen bestehen und bei denen eine Vielzahl unterschiedlicher Dateiformate angesprochen werden soll oder muss. • Gray Box Repository sind eine Mischform aus White und Black Box Repository, bei denen zwar ebenfalls eine hohe Abstraktion vom eigentlichen Dateiformat angestrebt wird, auf der anderen Seite aber auch Teile der genutzten API zum Laden bzw. Ansprechen der Dateien an höhere Schichten durchgereicht werden. Sie eignen sich grundsätzlich für die selben Einsatzzwecke wie Black Box Repository, wenn sich die anzusprechenden Dateiformate etwa auf eine bestimmte Gruppe einschränken lassen (z.B. baumstrukturierte Daten – dann können Sprachen wie XPath zur Abfrage genutzt werden – oder relationale Datenbanksysteme – dann kann nach oben hin SQL als Abfragesprache durchgereicht und verfügbar gemacht werden). Daneben wurde auch kurz auf die Thematik verteilter Anwendungen eingegangen, bei denen verschiedene Instanzen der Anwendung auf Rechnern in einem Netzwerk laufen. Hier ist es wichtig, dass diese Anwendungen untereinander ihre Daten teilen können. • Eine verbreitete Möglichkeit ist die Nutzung zentraler Server – etwa ein Datenbankserver. Dieser stellt sicher, dass der zentrale Datenbestand konsistent ist, indem der schreibende Zugriff sequenziell erfolgt. Bei diesem Modell kann der zentrale Server aber auch eine Bremse im System sein, wenn sehr viele Clients zeitgleich Anfragen stellen. • Alternativ dazu, kann jeder Client seine Daten lokal abspeichern und eine Synchronisation erfolgt später. Um nicht eigene Synchronisationsroutinen schreiben zu müssen, eignet sich hier die Verwendung von Versionsverwaltungssystemen wie etwa Subversion oder Git. Das Problem ist, dass die Synchronisation nicht in jedem Fall konfliktfrei verläuft – in diesem Fall muss der Benutzer manuell einen der Speicherstände auswählen. 37 KAPITEL 3. SPEICHERFORMATE UND DATENHALTUNG Black Box Abstraktion Starke Abstraktion von zugrunde liegenden Dateien, kein direkter Zugriff Geeignet für Nicht geeignet Szenarien, bei denen auf viele unterschiedliche Dateitypen zugegriffen werden muss oder Anforderungen wechseln; allgemein wenn keine Aussage über die Dateien gemacht werden kann Kurzfristige Projekte, Mi” niprojekte“, die ohnehin nur Unterstützung für beschränkte Dateitypen benötigen Gray Box Starke Abstraktion, allerdings Durchreichen einiger Zugriffe an höhere Schichten in der Applikation Zugriff auf unterschiedliche Dateitypen mit einigen gleichen Eigenschaften White Box Kaum oder keine Abstraktion, stattdessen direkter Zugriff höherer Schichten auf Dateiebene Sehr kleine oder spezielle Projekte mit wenig Anforderungen an verschiedene Dateiformate sowie für den Fall, das die zu unterstützenden Dateiformate keine gemeinsamen Eigenschaften aufweisen Große Projekte mit wechselnden Anforderungen und vielen verschiedenen Dateiformaten, die unterstützt werden müssen Sehr spezielle Applikationen mit feststehenden Dateitypen sowie wenn Entwicklungszeit im Vordergrund steht Tabelle 3.2.: Zusammenfassung Repositorytypen 38 4. Integration und Refactoring einer Dialogkomponente Dieses Kapitel soll sich nun der praktischen Aufgabenstellung zuwenden, die dieser Arbeit zu Grunde liegt. Damit bildet dieser Part zum einen eine Art Dokumentation. Auf der anderen Seite sollen die in den vorangegangenen Kapitel beschriebenen Sachverhalte examplarisch angewandt werden, um so deren Aussagekraft auf Basis einer realen Arbeit zu demonstrieren. 4.1. Ausgangssituation Die praktische Arbeit bezieht sich dabei auf die iSuite, ein intelligentes Dialogsystem zur Befragung von chronisch schmerzkranken Patienten. Das System beinhaltet dabei die eigentliche Dialogkomponente, sowie weitere Applikationen, die zur Auswertung und auch weiteren Verwaltung der Daten dienen. Die Grundidee ist dabei, den Patienten im Vorfeld des Arztgespräches bereits Fragen durch das System beantworten zu lassen, damit dann – zum eigentlichen Gespräch – dieses Wissen bereits genutzt werden und der Arzt gezielter auf den Patienten eingehen kann. 4.1.1. Die (alte) iSuite Die iSuite ist ein älteres Projekt, was im Laufe vieler Jahre entstanden ist, dabei immer wieder erweitert wurde und daher einigen Änderungen unterworfen war. Das hat unter Anderem zur Folge, dass Altlasten enhalten sind, was eine Weiterentwicklung erheblich ausbremst. Großes Ziel ist es daher, die einzelnen Applikationen stückweise zu erneuern. 39 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE 4.1.2. Überarbeitete Dialogkomponente Einen Anfang hat dabei die eigentliche Dialogkomponente gemacht, die im Rahmen einer Diplomarbeit bereits vollständig neuprogrammier wurde [19]. Dabei wurde unter Anderem auch die Datenhaltung überarbeitet, so dass nun Dateien im XML Format zur Speicherung des Wissens verwendet werden. 4.1.3. Aufgabe dieser Arbeit Die Aufgabe bestand nun darin, die neue Dialogkomponente in den bestehenden Rest der iSuite einzubetten. Denn um die neue Komponente ausgiebig zu testen, sind Feldtests notwendig, die allerdings nur zusammen mit der eigentlichen Programmsuite erfolgen kann. Dabei sind sowohl die bestehende iSuite als auch die neue Dialogkomponente für sich voll einsatzfähig. Wichtig ist allerdings, dass eine gemeinsame Datenbasis genutzt wird. 4.2. Analyse Zu Beginn der Projektarbeit stand dabei eine ausgiebige Analysephase, in der die Anforderungen genau untersucht wurden. Ziel sollte es sein, sich ein möglichst umfangreiches Bild zu machen, um dann die eigentliche Programmierarbeit so zielgerichtet wie möglich zu gestalten. 4.2.1. Datenbasis Die iSuite verwendet zur Speicherung ihrer Daten hauptsächlich eine Datenbank. Dabei sind sowohl Microsoft Access als auch Microsoft SQL Server als Backend möglich, da in der iSuite eine Abstraktionskomponente enthalten ist, die einen Zugriff auf beide Systeme kapselt. Als Basis zum (händischen) editieren der Wissensbasis wird ein Lisp-ähnliches Dateiformat verwendet, welches mit INI-Textdateien (gruppierten Schlüssel-/Wertpaaren) angereichert wird. Dieses Format ist allerdings fehleranfällig, da keine Standardeditoren existieren, mit denen diese Art Dateien komfortabel geschrieben werden können. Zwar gibt es in der Migrationskomponente der iSuite Routinen, die die Dateien prüfen, allerdings ist damit zum Testen der Wissensbasis stets eine Migration mit anschließendem Schreiben der Werte auf die Datenbank verbunden – was ein schnelles und unkompliziertes Testen unmöglich macht. 40 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE Die neugestaltete Dialogkomponente hat als Datenbasis hier XML eingeführt. Die Vorteile dieses Formates wurden bereits beschrieben: Unter anderem sei hier noch einmal die sehr gute Unterstützung durch gängige Editoren erwähnt, was ein Bearbeiten der Wissensbasis deutlich erleichtert (so kann die Syntax selbst leicht geprüft werden, ohne dass ein wirkliches Testen mit der gesamten Programmsuite nötig ist). Außerdem ließt die eigentliche Dialogkomponente ihre Daten stehts aus den XML Dateien. Damit ist zum Debuggen der Wissensbasis auch kein Datenbankserver erforderlich. Eine erste Verbindung zum Rest der iSuite wurde dadurch erreicht, dass die Ergebnisse der Patientenbefragung in die Datenbank der iSuite geschrieben wurden. Zur Integration muss nun die Lücke überbrückt werden, so dass sowohl die alten Komponenten als auch das neue Dialogsystem auf die selben Dateien zugreifen. 4.2.2. Kompatibilität zu alten Komponenten Eine wichtige Anforderung war dabei, dass die Kompatibilität zu den alten Komponenten erhalten bleiben musste. Wie bereits angedeutet, ist die iSuite historisch gewachsen. Damit ist aber auch nicht leicht beantwortbar, welche der alten Komponenten etwa direkt auf die Datenbank durchgreifen. Das hat einige Folgen: • Die Datenbank als (letztendlicher) gemeinsamer Speicher muss erhalten bleiben. Das ist aber durchaus gewollt, da dadurch auch ein zentraler Speicher gegeben ist. • Bestehende Datenbankschemata durften nicht verändert werden. Um nicht tief in das bestehende System eingreifen zu müssen, sollten diese also erhaltenwerden. Das Hinzufügen neuer Tabellen ist dagegen unerheblich – das ermöglicht, dass alle Informationen auf der Datenbank abgelegt werden können (und nicht nur ein Teil, so wie von der iSuite ursprünglich gehandhabt). 4.2.3. Stand der neuen Dialogkomponente Während die iSuite selbst bereits eine Art Gray Box Repository umsetzt – der Zugriff auf die Datenbank wird abstrahiert und ein alternativer Zugriff auf die eigentlichen Daten ermöglicht, während man dennoch direkte Abfragen via SQL erlaubt – so wurde in der neuen Dialogkomponente direkt auf die Dateien zugegriffen. In diesem Sinne gab es keine dedizierte Komponente, die das Laden der Daten verwaltet 41 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE und die Objekte der Wissensbasis zur Verfügung stellte. Damit kann hier von einem White Box Repositorium gesprochen werden. Das ist für den Integrationsschritt allerdings eher hinderlich: Denn um die bestehenden Strukturen beizubehalten, hätte an sehr vielen Stellen in der Komponente ein alternativer Ladepfad in den Quelltext eingefügt werden müssen. 4.2.4. Schlußfolgerungen Aus den genannten Beobachtungen wurden dann für die eigentliche Integration die folgenden Punkte abgeleitet: • Die iSuite selbst sollte bestenfalls als Black Box betrachtet werden: Zwar stand im Rahmen der Arbeit der Quelltext zur Verfügung, allerdings wäre der Aufwand, Anpassungen an sehr vielen der enthaltenen Komponenten durchzuführen, schlicht zu groß gewesen. Daher wurden die durch sie vorgegebenen Strukturen als fixiert angenommen. • Die Dialogkomponente selbst sollte von der Speicherung der Daten abgekapselt werden. Zwar sollte – aus Gründen des leichteren Debuggens – die Möglichkeit, die Wissensbasis direkt aus den XML Dateien laden zu können, unbedingt erhalten bleiben. Dennoch muss für die Releaseversion ein Laden nur von der Datenbank implementiert werden. Um dies bestmöglich umzusetzen, sollte die Umstellung auf ein Black Box Repository Model erfolgen. • Um ein Zusammenspiel beider Komponenten sicherzustellen, dennoch aber möglichst leicht erweiterbar zu bleiben und ein schnelles, agiles Entwickeln zu ermöglichen, sollten Adapterkomponenten verwendet werden, die die neuen Teile der iSuite mit den bestehenden verbinden. So kann ein Datenaustausch erfolgen, ohne dass die neugestaltete Komponenten an die Muster und Strukturen der alten iSuite gebunden werden. 4.3. Integrationsphase In der Integrationsphase fand die eigentiche Programmierung statt. Hier wurde das in der Analyse gesammelte Wissen ausgenutzt, um die Dialogkomponente in den Rest der iSuite einzubetten. 42 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE 4.3.1. iSuite.KnowledgeBase.Data Herzstück der Entwicklung war dabei die iSuite.KnowledgeBase.Data Bibliothek. Diese hat im Grunde zwei Aufgaben, die sich aus der Intention – die Bibliothek sollte ein Black Box Repository implementieren – ergeben: • Definition der Schnittstellen für auf der Bibliothek aufbauenden Komponenten. Nach unten hin sollten alle neuentwickelten Komponenten diese Schnittstellen nutzen, anstatt selbst auf die Dateien zuzugreifen. Damit kann das gewählte Dateiformat jederzeit gewechselt oder auch variiert werden, ohne zu viele Änderungen in Applikationen zu verursachen. • Speicherverwaltung. Kern der Bibliothek ist die Klasse Base (siehe 4.1). Diese enthält eine Reihe von Containern, die ihrerseits die eigentlichen Objekte der Wissensbasis enthalten. Die Komponenten, die die Wissensbasis nutzen, sollten sich nicht darum kümmern müssen, wie die Daten intern verwaltet werden. So ist es zwar nicht implementiert – da es bisher nicht benötigt wurde – aber anstatt alle Daten zu Programmbeginn zu laden, könnte auch ein alternativer Mechanismus angewandt werden, der die eigentlichen Daten erst dann lädt, wenn auf sie Zugegriffen wird. Nach außen hin sollte dies aber unerheblich sein, d.h. die Applikation sollte – abgesehen davon, dass sie der Wissensbasis mitteilen kann, welchen Mechanismus sie bevorzugt – nicht merken, wie intern geladen wird. 4.3.2. Das Pluginsystem Neben der Kernbibliothek wurden eine Reihe weitere Bibliotheken entwickelt, die im Namespace iSuite.KnowledgeBase.Data.Plugins verschiedene Lade- und Speicherroutinen zur Verfügung stellen. Diese sind als Klassen implementiert, die zur Laufzeit instantiiert und in einem Objekt der Klasse Base registriert werden. Die Wissensbasis nutzt dann zwei Events, die den registrierten Lesern und Schreibern mitteilt, dass die Wissensbasis initialisiert bzw. finalisiert wird. Bislang nutzen alle Plugins diese Events, um änfänglich die Daten in die Wissensbasis zu laden bzw. beim Beenden die Daten wieder zurückzuschreiben. Das Vorgehen ist in Abbildung 4.2 schematisch dargestellt. Daneben wäre es aber auch mit geringem Aufwand möglich, die Kernbibliothek so anzupassen, dass ein dynamisches Nachladen erfolgen kann. Dabei würden weitere 43 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE Graphic Question QuestionBlock Legend MaskItem MaskContainer QuestionsContainer LegendsContainer Base GraphicsContainer QuestionBlockContainer QuestionSet QuestionSetContainer Abbildung 4.1.: Klassendiagramm Container“ ” Ein (unvollständiger) Überblick über die iSuite.KnowledgeBase.Data Bibliothek. Herzstück ist die Klasse Base. Diese stellt den Zugriff auf verschiedene Containerklassen bereit, die wiederum die eigentlichen Daten enthalten. 44 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE App 1 App 2 App N Wissensbasis XML Reader XML Writer XML Lisp Reader Lisp DB Reader DB Abbildung 4.2.: Wissensbasis mit Plugins Die Wissensbasis selbst stellt keine Lade- und Speicherroutinen bereit. Vielmehr werden dafür dedizierte Plugins genutzt. Damit wird erreicht, dass die Wissensbasis selbst bereits vollkommen unabhängig von spezifischen Dateiformaten wird. Dieses System ermöglicht es, Änderungen an den Dateiformaten vorzunehmen, ohne dass die auf der Wissensbasis aufbauenden Applikationen angefasst werden müssen. Auch das Hinzufügen komplett neuer Formate ist ohne Probleme möglich; es werden lediglich neue Plugins zum Laden und (falls benötigt) Schreiben hinzugefügt. 45 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE Events spezifiziert, die genutzt werden, um mitzuteilen, dass eine Clientapplikation bestimmte Daten anfordert. Das Plugin würde dann die Chance erhalten, in seinem Dateibestand nach den Daten zu suchen und sie in die Wissensbasis einzufügen, so dass der anschließende Zugriff des Clients tatsächlich ein Objekt zurückliefert. Durch die starke Abstraktion könnte eine solche Erweiterung implementiert werden, ohne dass die auf der Bibliothek aufbauenden Anwendungen geändert werden müssen. Native Plugins Folgende native Plugins existieren, die genutzt werden, um auf spezielle Dateiformate zuzugreifen: LspReader Dieses Plugin dient dazu, die Wissensbasis direkt aus den von der ursprünglichen iSuite genutzten Lisp-Dateien zu lesen. XmlReader, XmlWriter, XmlDefaults Diese Plugins realisieren das Lesen bzw. Schreiben der Wissensbasis unter Verwendung des XML Formates. Die XmlDefaults Bibliothek stellt dabei lediglich gemeinsam genutzte Definitionen bereit (etwa der bevorzugten Dateinamen). So können Änderungen in den beiden anderen Plugins leicht realisiert werden, indem diese gemeinsam genutzte Bibliothek geändert wird. SqlFileExporter Dieses spezielle Plugin dient dazu, die Wissensbasis in ein SQL Skript zu überführen, welches die statischen Parts der Wissensbasis bei Ausführung direkt in eine Datenbank schreibt. Bei Verwendung spezieller Parameter wird dabei eine abgewandelte SQL Datei erzeugt, welche vom Migrationswerkzeug der iSuite verwendet werden kann. Adapter zur iSuite Neben dem Zugriff auf konkrete Dateien ermöglichen die folgenden Plugins eine weitgehende Interoperabilität mit der bestehenden iSuite: LegacyDatabaseReader Dieses Plugin nutzt eine Bibliothek der iSuite, um Zugriff auf die verwendete Datenbank zu erhalten und die Wissensbasis von dieser zu lesen. LegacyMandatoryInitializationHelper Dieses sehr spezielle Plugin dient dazu, um einige oft genutzte Überprüfungen beim Starten einer typischen iSuite-Applikation 46 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE durchzuführen, so etwa das Prüfen, ob ein Arzt im System angemeldet ist, der Datenbankserver läuft und so weiter. Dabei werden ebenfalls Bibliotheken der alten iSuite verwendet. Die Idee dieses Plugins ist einfach: Anstatt in jeder Applikation die Prüfungen zu implementieren, werden diese in einem Plugin gesammelt. Damit ist es weiterhin möglich, die Prüfungen (etwa für Debuggingzwecke) sehr schnell zu deaktivieren (indem das Plugin einfach nicht registriert wird). LegacyPatientBridge Dieses Plugin lädt die Patientendaten aus der Datenbank der iSuite. Es hat damit einen ähnlichen Nutzen wie das LegacyDatabasePlugin, allerdings dient dieses nur zum Laden der statischen Parts der Wissensbasis, während dieses Plugin die dynamischen lädt. Wird dieses Plugin genutzt, so kann etwa die Dialogkomponente ohne weiteres Zutun die Antworten des Patienten auf die Fragen in die Datenbank schreiben – bzw. passiert dies automatisch im Hintergrund. Alternativ können auch die XML Plugins so konfiguriert werden, dass sie Patientendaten lesen und schreiben. Dass sämtliche Zugriffe auf die alten Strukturen via Plugins erfolgt, hat dabei einen großen Vorteil: Neuentwickelte Komponenten sind nicht an die alten Strukturen gebunden. Natürlich müssen einige Kompromisse beim Design eingegangen werden – so wurden etwa die Klassen rund um die Verwaltung der Patienten in der neuen Kernbibliothek mit virtuellen Methodenaufrufen und Properties versehen (während dies bei den anderen Klassen – eben dem statischen Teil der Wissensbasis – vermieden wurde). Allerdings hat dies keinen direkten Einfluss auf die Clientapplikationen. 4.4. Neue und angepasste Applikationen Neben der entwickelten Kernbibliothek zur Verwaltung der Wissensbasis und den verschiedenen Plugins, mussten auch einige bestehende Applikationen angepasst werden bzw. wurden von Grund auf neu geschrieben. 4.4.1. Dialogkomponente An erster Stelle steht dabei die eigentliche Dialogkomponente. Dort wurden die direkten Dateizugriffe entfernt. Stattdessen wird nun stets auf ein Wissensbasisobjekt 47 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE aus der Repositorybibliothek zurückgegriffen. Auf diese Art und Weise ist es weiterhin möglich, die Dialogkomponente selbstständig – also ohne laufenden Datenbankserver und iSuite – laufen zu lassen. Gleichsam kann aber auch leicht auf die Datenbank zugegriffen werden, um eine gemeinsame Nutzung der Daten zu realisieren. 4.4.2. KnowledgeBase Converter Dieses Kommandozeilenwerkzeug dient zum Konvertieren der Wissensbasis in verschiedene Formate. Dabei wird im Prinzip die Wissensbasis in einem der unterstützten Formate entgegengenommen und in ein beliebiges, implementiertes Ausgabeformat überführt. Der Nutzen dieses Werkzeugs ergibt sich hauptsächlich im Zusammenspiel mit dem Migrationstool. 4.4.3. MigTool Das Migration Tool (kurz MigTool) dient dazu, bei einem Upgrade der iSuite (oder auch einer Neuinstallation) die Daten in der Datenbank anzupassen. Um möglichen Konflikten mit alten Komponenten zu entgehen, wurde dieses Werkzeug nur geringfügig geändert: Und zwar wurden einige Bezeichner geändert, um den neuen Bedingungen gerecht zu werden (anstatt nur einen Teil des statischen Wissens zu schreiben, wird nun der gesamte statische Teil des Wissens transferiert; dies spiegelt sich in den neuen Bezeichnernamen wieder). 4.4.4. KnowledgeBase Editor Diese Anwendung wurde vom QuestionEditor der neuen Dialogkomponente inspiriert [19]. Rein prinzipiell hätte auch dieser angepasst werden können. Nach einer Aufwandseinschätzung wurde der alte Editor allerdings verworfen und stattdessen von Grund auf neu geschrieben, um besser mit der neuen Kernbibliothek auszukommen. Der Editor erlaubt dabei das Editieren der Objekte in einer bestehenden Wissensbasis. Ein weiterer Ausbau dieses Werkzeuges würde sich dabei als hilfreich erweisen: Denn zum Einen wäre damit ein komfortables Programm vorhanden, um das Wissen bearbeiten zu können (welches auch von Fachexperten aus dem Bereich der Medizin benutzt werden könnte); zum Anderen würden damit auch einfache Fehler (et- 48 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE wa Syntaxfehler) vermieden, da das Schreiben der Dateien durch die bereitgestellten Plugins der Kernbibliothek erfolgt und damit die Richtigkeit der Daten quasi garantiert wird. 4.5. Schlußphase An dieser Stelle sei auch noch auf eine interessante Begebenheit in der Schlußphase des Projektes hingewiesen: In dieser wurden noch einige neue Anforderungen eröffnet, die nicht von Anfang an klar kommuniziert wurden: • Die Anzahl der Artefakte sollte möglichst klein sein. Um die Installation der iSuite auf einem Endnutzersystem möglichst einfach zu halten, sollte es nicht zu viele verschiedene Bibliotheken geben. • Möglichst keine externen Abhängigkeiten. Der erste Punkt ist daher kritisch, da vor allem die neue Basisbibliothek aber auch die bestehende, überarbeitete Dialogkomponente in sehr kleine Bibliotheken unterteilt sind. Bei der Basisbibliothek macht das auch Sinn, denn dort ist die Zahl der Artefakte durch die unterstützten Dateiformate und Speicherbackends gegeben. Um dennoch die Installation und Konfiguration zu vereinfachen, wurde die Zahl der Bibliotheken deutlich verringert, indem einige der Plugins nun in gemeinsamen Bibliotheken liegen. So befinden sich nun XmlReader und XmlWriter in einer gemeinsamen Binärdatei, genauso wie die Plugins zum Zugriff auf die Datenbank via der iSuite.Utils Bibliothek. Der SQL Exporter und Lisp-Reader befinden sich noch in einzelnen Dateien, allerdings werden beide in einer Produktivinstallation der iSuite nicht benötigt, so dass dies nicht weiter ins Gewicht fällt. Die zweite Anforderung hingegen war deutlich problematischer. Die Dialogkomponente führte gleich zwei externe Abhängigkeiten ein: Zum Einen wurde C#Prolog für die Dialogführung verwendet. Zum Anderen wurde zur graphischen Darstellung die Windows Presentation Foundation verwendet. Da der Aufwand, diese Änderungen in das bestehende Programm zu integrieren, recht hoch gewesen wäre, wurde die Dialogkomponente noch einmal von Grund auf neugeschrieben. Da die eigentlichen Kernfunktionen in der neuen Basisschicht inplementiert werden, konnte diese Aufgabe sehr schnell zu Ende gebracht werden. Aus dem ursprünglichen Rewrite wurden dabei die Grundstrukturen und -ideen übernommen, allerdings auch einige 49 KAPITEL 4. INTEGRATION UND REFACTORING EINER DIALOGKOMPONENTE Vereinfachungen vorgenommen, um eine spätere Anpassung möglichst einfach zu gestalten. 50 5. Zusammenfassung und Ausblick Im nun folgenden, letzten, Abschnitt soll nun nocheinmal kurz zusammengefasst sowie ein Ausblick auf anstehende Schritte bei der Entwicklung der iSuite gegeben werden. 5.1. Was wurde geschafft? Es wurde eine komplett neue Bibliothek zur Abstraktion der Datenhaltung eingeführt. Diese stellt eine gute Grundlage für zukünftige Entwicklungen dar, da so das Erstellen neuer Programme für die iSuite deutlich leichter werden sollte und diese von konkreten Systemen unabhängiger werden. Die Mächtigkeit dieser neuen Bibliothek wurde in der Spätphase des Projektes sogar direkt getestet: So wurden in der Endphase noch neue Anforderungen enthüllt: Die Komponenten der iSuite sollten möglichst wenige externe Abhängigkeiten aufweisen. Dem stand die vorliegende Dialogkomponente mit ihren Abhängigkeiten zur Windows Presentation Foundation sowie C#Prolog entgegen. Mehr als eine Art Prototyp wurde dabei ein kompletter Rewrite der Dialogkomponente erstellt – welcher innerhalb kürzester Zeit einsatzbereit war. Auch dieser Prototyp ist vollkommen unabhängig von konkreten Speichersystemen: Ein Beweis für die Mächtigkeit der neuen Abstraktionsschicht. 5.2. Weitere Schritte Durch die Entwicklung der iSuite.KnowledgeBase.Data Bibliothek ist ein wichtiger Schritt bereits getan: Wenn zukünftig beim Redesign anderer Komponenten ebenfalls strikt gegen diese Bibliothek programmiert wird, wird automatisch ein System erhalten, welches vollkommen unabhängig von der verwendeten Wahl des Speicherformates ist. Das macht nicht nur das eigentliche Entwickeln einfacher (im Hintergrund muss dann etwa nicht die Datenbank laufen sondern es kann lokal aus den 51 KAPITEL 5. ZUSAMMENFASSUNG UND AUSBLICK XML Dateien geladen werden). Man könnte auch versuchen, neue Techniken zu integrieren. Dazu wurde in der Vorgängerarbeit bereits vorgeschlagen, als physikalisches Medium zur Befragung keinen PC oder Laptop zu verwenden, sondern stattdessen Tablets. Diese dürften zwecks Usability in der Tat eingängiger sein, als Standardhardware. Dafür müsste allerdings nicht nur die Oberflache an die Bedienung per Touchscreen angepasst werden. Es wäre auch ratsam, nicht die gesamten Informationen (etwa das komplette statische Wissen) auf einmal zu laden. Stattdessen könnte etwa ein neues Plugin einen zentralen Server befragen, um dann nur die Daten zu laden, die für den gerade befragten Patienten benötigt werden. In diesem Zusammenhang wäre eine Portierung der iSuite auf Mono und damit andere Systeme interessant1 . Denn vor allem im Tabletbereich sind Betriebsysteme wie iOS oder Android stark vertreten. Die neue Repository Library bietet dazu ebenfalls gute Grundlagen, denn sie selbst ist nicht an ein System gebunden (tatsächlich werden nur Standardbibliotheken von C# verwendet, damit ist eine Portierung auf Mono sofort möglich). Plattformabhängig sind tatsächlich nur die einzelnen Plugins. Darin liegt allerdings auch der große Vorteil: Denn die Stellen im Quelltext, die dann einer Anpassung bedürfen sind überschaubar und beschränken sich auf einzelne Komponenten. Ebenfalls von Vorteil ist die Abkopplung von Programmlogik und Benutzeroberfläche im neuen Dialogsystem. Zwar gibt es noch einige wenige harte Abhängigkeiten auf Windows-spezifische GUI-Bibliotheken2 ; diese sollten sich allerdings recht einfach entfernen lassen. 5.2.1. Klärungsbedarf bei der Lizenz der C#Prolog Bibliothek Ein wichtiger Punkt, der noch dringend zu klären ist, ist die Verwendung der C#Prolog Bibliothek. Diese wird als Backend in der Dialogkomponente verwendet, um die Dialoge zu führen. Diese Bibliothek ist veröffentlicht unter der GNU GPL. Im Falle einer Bibliothek bedeutet das: Jedes Projekt, welches gegen diese Bibliothek linkt, muss 1 Hier sei bereits angemerkt, dass die Datenabstraktionsschicht und auch die anderen Projekte, die im Zuge dieses Projektes entwickelt wurden, bereits mit Mono kompatibel sind. Wird bei einem Rewrite oder Redesign anderer bestehender Komponenten auf die Kompatibilität mit Mono geachtet, sollte es nicht schwierig sein, ein sehr flexibles und plattformunabhängiges System zu erhalten. 2 Der neue Prototyp der Dialogkomponente ist eine reine Windows.Forms Anwendung. Damit läuft er bereits unter anderen Systemen als Windows. Sollten zukünftig andere Betriebssysteme tatsächlich in Erwägung gezogen werden, wäre es dennoch eine Überlegung wert, die Oberflächen an die jeweiligen Systeme anzupassen (etwa durch Nutzen von Gtk# für Linux und CocoaSharp für Mac OS oder die direkte Nutzung von Qt für .NET, welches intern dann die jeweils nativen Systeme zur Darstellung nutzt und die Anwendung so besser in die Umgebung einbettet). 52 KAPITEL 5. ZUSAMMENFASSUNG UND AUSBLICK ebenfalls unter der GNU GPL lizensiert werden. Das hätte zur Folge, dass mindestens Teile der iSuite ebenfalls unter der GNU GPL veröffentlicht werden müssen. Allerdings ist hier noch einmal eine genaue Prüfung anzustellen (in der Tat wird dieser Fakt erst dann wichtig, wenn es um eine Veröffentlichung der neuen iSuite Version mit der redesignten Dialogkomponente geht). Wird alternativ der neue Prototyp der Dialogkomponente genutzt, kann diese Frage getrost umgangen werden. Denn diese nutzt einen eigenen Mechanismus zum Führen der Dialog. Dieser Mechanismus ist zwar nicht in der Lage, Fragen bedingt zu stellen. Dafür ist es recht einfach, einen anderen Mechanismus zu integrieren, der genau das realisiert – indem einfach die Entsprechende Spezialisierung einer Klasse im System ausgetauscht wird. Damit kann man die Entscheidung vorerst vertagen oder ganz auf ein anderes Backend zum Führen der Dialoge umsteigen (z.B. eine weitere Eigenentwicklung, bei der die Wahl der Lizenz frei ist). 5.2.2. Nutzen des XML Formates Bisher hat die Umstellung auf XML nur den Vorteil erbracht, dass standardisierte Bibliotheken zum Laden und Speichern verwendet werden können und so der Datenbestand weniger anfällig gegenüber kleineren Fehlern beim Schreiben ist. Allerdings werden damit die Vorzüge des Formates bislang noch keinesfalls ausgereizt. Ein erster Schritt etwa wäre es, eigene DTDs oder XSDs einzuführen, die beim Laden zur Kontrolle der XML Dateien verwendet werden. Da derzeit die XML Dateien direkt aus den alten Lisp Dateien generiert werden, wird programmseitig keine Prüfung auf die Validität hin gemacht. Das sollte sich natürlich ändern, sobald Erweiterungen an der Wissensbasis erfolgen (die dann ja direkt in den XML Dateien erfolgen werden). Indem zum Testen (zumindest der grundsätzlichen Struktur der Dateien) auf solche bereits vorgegebenen Mechanismen zurückgegriffen wird, bleiben die Quelltexte der betroffenen Teile des Projektes sehr viel übersichtlicher. Man könnte aber sogar noch weitergehen und etwa auf Basis von XSLT Skripten Testroutinen schreiben, welche die Wissensbasis prüfen. Damit ließen sich auch Tests auf Dinge wie Eindeutigkeit von Identifikatoren oder das Finden von nicht genutzen Objekten in der Wissensbasis durchführen. 53 KAPITEL 5. ZUSAMMENFASSUNG UND AUSBLICK 5.2.3. Weitergehendes Redesign und Neuentwicklungen Was ebenfalls folgen sollte, ist die weitergehende Umstellung auf die neue Bibliothek zum Speicherzugriff und damit einhergehend – zumindest wo sinnvoll – ein Refactoring bzw. Redesign vorhandener Komponenten. Damit werden definitiv auch Erweiterungen an den entwickelten Bibliotheken folgen; durch den Abstraktionsgrad von den Speicherformaten allerdings sollte sich dies nicht weiter auf vorhandene Clients dieser auswirken. Ebenfalls folgen können neue Applikationen. So ist etwa derzeit eine Anwendung in Entwicklung, die zum Erzeugen von gedruckten Versionen der Dialoge genutzt werden und diese dann – nach dem Ausfüllen durch den Patienten zu Hause – wieder einlesen kann. Daneben sind noch weitere Neuerungen denkbar (etwa eine Version der Dialogkomponente für Tablets). 5.2.4. Anpassung der Datenbankschemata Unabhängig vom eigentlichen Redesign der restlichen Komponenten sollte unbedingt an einer Modernisierung der Datenbankschemata gearbeitet werden (ob diese nun schon von den Legacy-Komponenten genutzt werden müssen oder nicht sei dahingestellt). Das derzeitige System zum Schreiben – gerade der Episoden für die einzelnen Patienten – ist hochgradig fehleranfällig. So werden etwa bei den Episoden Listen von Werten in ein einzelnes String-Feld kodiert. Hier sollte unbedingt auf datenbanktypische Lösungen zurückgegriffen werden. Ebenfalls kann überlegt werden, ob nicht eine weitergehende Spezialisierung der einzelnen Episoden erfolgen kann, anstatt wirklich alle gleich zu behandeln. 5.2.5. Ausbau des Editors für die Wissensbasis Derzeit ist der Editor nur in der Lage, eine bestehende Wissensbasis zu editieren. Das bedeutet zwar bereits, dass viele kleinere Fehler vermieden werden können. Allerdings wären hier deutlich mächtigere Werkzeuge wünschenswert. Vor allem das Hinzufügen und Entfernen von Einträgen in die MASK Struktur wäre vorteilhaft. 54 KAPITEL 5. ZUSAMMENFASSUNG UND AUSBLICK 5.3. Lessons Learned Im Folgenden sollen einige Punkte angesprochen werden, die sich im Laufe der Arbeit als besonders nützlich, interessant oder wichtig herausgestellt haben. 5.3.1. Analysephase bei größeren Projekten ist wichtig Die Analysephase zu Beginn des Projektes hat sich als äußerst nützlich erwiesen. Zwar kann bei kleineren Projekten diese Phase durchaus recht kurz gehalten werden, bei Größenordnungen in die die iSuite hineinfällt sollte sie allerdings recht ausgiebig sein. Ebenfalls in dieser Phase kann das Schreiben kleinerer Prototypen angesiedelt sein – hierfür eignen sich Skriptsprachen wie Perl oder Ruby gut, da damit sehr schnell Ergebnisse erziehlt werden können. 5.3.2. Abstraktion der Datenhaltung Als problematisch hat sich der Fakt herausgestellt, dass die ursprüngliche iSuite nur eine Art Gray Box Repository zum Zugriff auf die Daten implementiert. Zwar wird für viele Zugriffe eine Abstraktion angeboten, doch durch die Möglichkeit, direkt auf die genutzten Datenbanken durchzugreifen, konnten im Nachhinein keine Einschränkungen gemacht werden, welche Komponenten wie stark von den derzeitigen Datenbankschemata abhängen. Für Projekte in dieser Größenordnung kann man also fast annehmen: Die Implementierung einer Black Box zum Datenzugriff dürfte fast immer lohnen. Der Zeitaufwand, der dafür anfällt, wird sich – vor allem bei wechselnden Anforderungen – stets auszahlen (und ist abgesehen davon wohl auch in Anbetracht der Gesamtzeit, die für das Projekt aufgewand werden muss, vernachlässigbar). 5.3.3. Design Pattern vs. Ease of Code Design Pattern werden häufig als guter Stil in der Programmierung betrachtet. In der Tat hilft ihre Verwendung oft, um Standardprobleme in einer wohldefinierten Art und Weise zu lösen. Auf der anderen Seite sollte man den Einsatz auch gut abwägen, da sie sich bei einigen Problemstellungen schlicht nicht lohnen. Ein Beispiel ist das in der Dialogkomponente verwendete Model-View-View Model Pattern (MVVM). Die Beschreibung dieses Pattern hört sich vorerst recht gut an, allerdings – so zumindest 55 KAPITEL 5. ZUSAMMENFASSUNG UND AUSBLICK der gefühlte (und damit subjektive!) Eindruck – spielt es seine Vorzüge nur dann wirklich aus, wenn verschiedene Views gleichzeitig auf den selben Daten operieren sollen. Das ist im Falle der Dialogkomponente aber nicht gegeben. Ein einfacheres Muster wäre an dieser Stelle daher womöglich besser gewesen, da es die Les- und Nachvollziehbarkeit des Codes erhöht hätte. 56 A. Literatur [1] Prof. Dr. U. Aßmann. Datenablage (Datenbasis, Repositorium) und Austauschformate. Vorlesungsfolien. URL: http://st.inf.tu- dresden.de/Lehre/ WS10-11/dpf/slides/sew-11-repository.pdf. [2] Prof. Dr. U. Aßmann. Design Patterns and Frameworks -Introduction. Vorlesungsfolien. URL: http://st.inf.tu- dresden.de/Lehre/WS10- 11/dpf/ slides/01-intro.pdf. [3] Anders Berglund u. a., Hrsg. XML Path Language (XPath) 2.0 (Second Edition). URL : http://www.w3.org/TR/2010/REC-xpath20-20101214/. [4] Paul V. Biron und Ashok Malhotra, Hrsg. XML Schema Part 2: Datatypes Second Edition. URL: http://www.w3.org/TR/2004/REC-xmlschema-2-200410 28/. [5] Tim Bray u. a., Hrsg. Extensible Markup Language (XML) 1.0 (Fifth Edition). URL: http://www.w3.org/TR/2008/REC-xml-20081126/. [6] Shirley Y.Y. Cheng, Tiffany Barnett White und Lan Nguyen Chaplin. The ef” fects of self-brand connections on responses to brand failure: A new look at the consumer-brand relationship“. In: Journal of Consumer Psychology In Press, Corrected Proof (2011), S. –. ISSN: 1057-7408. DOI: DOI:10.1016/j.jcps.2011. 05.005. URL: http://www.sciencedirect.com/science/article/ pii/S105774081100057X. [7] James Clark und Steve DeRose, Hrsg. XML Path Language (XPath) Version 1.0. URL : http://www.w3.org/TR/1999/REC-xpath-19991116/. [8] Douglas Crockford. RFC 4627 (JSON). html/rfc4627. URL : http : / / tools . ietf . org / [9] David C. Fallside und Priscilla Walmsley, Hrsg. XML Schema Part 0: Primer Second Edition. URL: http://www.w3.org/TR/2004/REC- xmlschema- 020041028/. 57 Literatur [10] Google Protocol Buffers. protocolbuffers/. URL : http : / / code . google . com / apis / [11] Roberto Ierusalimschy, Luiz Henrique de Figueiredo und Waldemar Celes Filho. Lua—An Extensible Extension Language“. In: Software: Practice and Expe” rience 26.6 (1996), S. 635–652. ISSN: 1097-024X. DOI: 10.1002/(SICI)1097024X(199606)26:6<635::AID- SPE26> 3.0.CO;2- P. URL: http:// dx.doi.org/10.1002/(SICI)1097-024X(199606)26:6<635::AIDSPE26>3.0.CO;2-P. [12] Adam Jacobs. The pathologies of big data“. In: Commun. ACM 52 (8 2009), ” S. 36–44. ISSN: 0001-0782. DOI: http://doi.acm.org/10.1145/1536616. 1536632. URL: http://doi.acm.org/10.1145/1536616.1536632. [13] Michael Kay, Hrsg. XSL Transformations (XSLT) Version 2.0. URL: http://www. w3.org/TR/2007/REC-xslt20-20070123/. [14] KDE KIO API Dokumentation. URL: http : / / api . kde . org / 4 . x - api / kdelibs-apidocs/kio/html/index.html. [15] Sergey Melnik u. a. Dremel: interactive analysis of web-scale datasets“. In: ” Proc. VLDB Endow. 3 (1-2 2010), S. 330–339. ISSN: 2150-8097. URL: http : / / dl.acm.org/citation.cfm?id=1920841.1920886. [16] Jan-Eike Michels u. a. Die SQL-Normen“. Übers. von Andreas Osterhold und ” Peter Pistor. In: it - Information Technology (2003). ISSN: 45. URL: http://www. ai.wu.ac.at/˜wyk/dbs/pdf/SQL-DIN-Mitt-4-2004.pdf. [17] Uwe Petersohn u. a. Problem solving with Concept- and Case-based Reaso” ning“. In: Recent Developments in Artificial Intelligence Methods. Hrsg. von T. Burczyńsky, W. Cholewa und W. Moczulski. Gliwice: AI-METH Series, 2009. [18] Qt 4 XQuery Documentation. xmlprocessing.html. URL : http://doc.qt.nokia.com/latest/ [19] Guido Scheffler. Redesign eines medizinischen wissensbasierten Systems un” ter Nutzung des .NET Frameworks als Plattform für die Entwicklung, der logischen Programmierung sowie unter Anlehnung an das Entwurfs-Pattern Model-View-ViewModel“. Diplomarbeit. 2011. [20] The Wireshark Team. Libpcap File Format. URL: http://wiki.wireshark. org/Development/LibpcapFileFormat. 58 Literatur [21] Henry S. Thompson u. a., Hrsg. XML Schema Part 1: Structures Second Edition. URL : http://www.w3.org/TR/2004/REC-xmlschema-1-20041028/. 59