homeprojekte_findenfreiberufler_softwareagenturen_stellen_sich_vorprintmagazinnewsletter_abonnierenkontakt

Top-Projekte

Hier gelangen Sie zu den aktellen Projeckten von:

Resoom Projects

Zum Wert von Software: Technologieneutrale Implementierung von funktionalen Anforderungen
Arne Lewinski

In der Software-Entwicklung gehört die Schichtentrennung zum guten Ton. Leider bezieht man sich dabei viel zu häufig auf die eingesetzten Technologien. Wünschenswerter ist es jedoch, den Fokus auf den eigentlichen Wert einer Software zu legen, nämlich inwiefern sie die Anwender bei ihrer Arbeit unterstützt, und weniger auf technologische Details. Welche Bedeutung hat in diesem Zusammenhang Technologieneutralität?

Dipl. Wirtschaftsinformatiker(FH) Arne Lewinski: „Man kann hier durchaus von Technologie-Schichten reden, hingegen ist die Geschäftslogik über mehrere Schichten verteilt.“

Bei seriöser Betrachtung sind für die Ermittlung der Fachanforderungen bis zu 30 Prozent der Projektzeit zu veranschlagen, was einen nicht gerade zu vernachlässigenden Kostenblock darstellt. Unter normalen Umständen und erst recht in wirtschaftlich schwierigen Zeiten wird man Probleme haben, Kunden von der Notwendigkeit der Re-Implementation bereits festgelegter Anforderungen oder redundanter Implementationen zu überzeugen, wenn man bloß Technologien gegeneinander austauscht.

Schichtung als Basis flexibler Architekturen
Schichten in einer Software haben den Zweck, die unterschiedlichen Anforderungen der Software zu trennen. Die übliche Dreiteilung GUI-Modell-Persistenz ist in den meisten Fällen zwar nicht ausreichend, soll hier aber als Referenz genannt werden. Schichten bauen aufeinander auf; die obere Schicht ist abhängig von der Schnittstelle und Funktionserfüllung der unteren Schicht - umgekehrt gilt dies jedoch nicht. Folglich gibt es keine zyklischen Abhängigkeiten. Jede Schicht für sich betrachtet kann gegen eine andere ausgetauscht werden, vorausgesetzt die beabsichtigte Aufgabenerfüllung bleibt gewährleistet. Falls eine Schicht durch eine schnellere, speichersparendere oder transparentere Implementierung ersetzt werden soll, ist der gut durchdachte Aufbau der Schnittstellen entscheidend.

Ein Beispiel
Die Schichtentrennung ausschließlich mit dem Einsatz unterschiedlicher Technologien zu begründen, birgt Gefahren. Die Benutzeroberfläche (z. B. JAVA-Swing) einer geschichteten Anwendung fordert die Eingabe einer E-Mail-Adresse. Die formale Prüfung der E-Mail-Adresse erfolgt lediglich auf der Oberflächenebene. Bei einem direkten Zugriff auf die Schicht unterhalb der Oberfläche bei automatischer Verarbeitung, wäre es möglich, diese Restriktion zu umgehen. Und bei der Umstellung der Oberfläche auf eine andere Technologie (z. B. JSP), kann dies den Verlust von Konsistenzbedingungen bedeuten, falls diese nicht sauber dokumentiert sind. Man kann hier durchaus von Technologie- Schichten reden, hingegen ist die Geschäftslogik über mehrere Schichten verteilt. Die korrekte Vorgehensweise in diesem Fall wäre eine Prüfung sowohl in der Oberfläche und sowieso im Modell. Da jede Schicht eine eigenständige Aufgabe erfüllt, ist eine doppelte Implementierung gerechtfertig. Die Oberfläche kann die formale Prüfung der E-Mail-Adresse vornehmen und spart damit Server-Kommunikation. Es handelt sich um eine Performance-Optimierung. Das Modell hat eine andere Aufgabe, nämlich die Sicherstellung der Konsistenz der Daten.

Geschäftslogik in technologieneutraler Schicht
Es liegt der Versuch nahe, die Geschäftslogik in einer Schicht zu kapseln, die robust gegen Technologiewechsel anderer Schichten abgeschirmt ist. Generell geht man bei einer technologieunabhängigen Implementation so vor, dass man die Trennung der funktionalen Anforderungen von den Aspekten und den nicht-funktionalen Anforderungen vornimmt. Das, was an Anforderungen dann noch übrig bleibt, sind die fachlichen Elemente der Software. Sie stellen genau das dar, was die Mitarbeiter der Fachabteilung mit der Aufgabenerfüllung der Software verbinden. Es werden strukturbildende (Datenmodell), ablaufbildende (Workflow) und konsistenzbildende Elemente (Regeln) ermittelt. Dann implementiert man die Geschäftslogik nur auf Basis dessen, was unbedingt notwendig ist. Heutzutage ist dies üblicherweise die Basis-API einer objektorientierten Programmiersprache. Objektorientierte Programmiersprachen bieten die notwendigen Mittel für die Abstraktion von der konkreten Implementation einer Schicht. Das wichtigste hier anzuwendende Entwurfsmuster ist das der „abstrakten einmal Geschäftslogik in die DAOs wandert und dann bei einem Technologiewechsel nicht mehr zur Verfügung steht. Dies ist nur mit einiger Erfahrung des Entwicklers zu vermeiden.

Abstraktion von der Datenspeicherung
Wenn man einen extremen Ansatz verfolgt, liegt es nahe, selbst das Vorhandensein von Objektattributen in der Geschäftslogik als Verstoß gegen die Aufgabentrennung der Schichten zu werten. Hinsichtlich der Schichten sollte es egal sein, wo die Daten gespeichert werden, mit der die Geschäftslogik arbeitet. Ob nun auf einem flüchtigen oder nicht-flüchtigen Speicher zugegriffen wird, muss dann transparent implementiert sein. Erst in der konkreten Implementation der Persistenzschicht erfolgt die Entscheidung, ob persistent oder transient gearbeitet wird. Eine transiente Variante der Speicherung der Daten zu unterstützen, hat den Vorteil, dass auch eine komplizierte Geschäftslogik relativ einfach, schnell und ohne Overhead getestet werden kann. Es ist ein Unterschied in der Produktivität, ob der Durchlauf der JUnit-Tests 5 Sekunden im Hauptspeicher oder 50 Sekunden mit Datenbankinteraktivität dauert, wenn man eigentlich nur einen Algorithmus der Geschäftlogik testen möchte.

Zur Caching-Problematik
Fast jeder Entwickler verwendet Objektvariablen in den Geschäftsobjekten. Ein üb liches Szenario ist das Laden eines Geschäftsobjekts mit all seinen Attributen aus der Datenbank. Der Medienwechsel der Daten erfolgte in der Hoffnung, sehr schnell mit den im Hauptspeicher verfügbaren Daten arbeiten zu können. An dieser Stelle werden aber Geschäftslogik und Caching- Konzept vermischt. Wer mit JPA arbeitet, kennt die Konfiguration von Ladestrategien für mengenwertige Assoziationen. Es handelt sich dabei um die Festlegung, welche Daten schon vorab in den Hauptspeicher geladen werden sollen. Die entscheidende Frage dabei ist: Handelt es sich um ein strukturbildendes, ablaufbildendes oder konsistenzbildendes Element, welches der Geschäftslogik zuzuordnen ist? Die einzige richtige Antwort kann nur lauten: Nein!

Ausnahmen bestätigen die Regel!
Es gibt dennoch Situationen, in denen die saubere Trennung der Geschäftslogik von den nicht-funktionalen Anforderungen und den Aspekten nicht hilft und eine Neu- Implementierung nicht umgangen werden kann. Der Wechsel von .NET zu JAVA ist ein Grund. Des Weiteren können bestimmte nicht-funktionale Anforderungen wie hohe Geschwindigkeiten Technologieabhängigkeit rechtfertigen. Dies ist insbesondere im Bereich Reporting der Fall. Dort werden sehr viele Daten verarbeitet, die am Ende nicht als Objektmodell dargestellt werden. Es sind dann andere Konzepte zu verfolgen.
Über den Autor
Der fachliche Schwerpunkt des Dipl. Wirtschaftsinformatikers (FH) Arne Lewinski liegt im Bereich Analyse, Design, Implementation und Test von Client-Server-Software. Darüber hinaus verfügt er über umfangreiche Kenntnisse in den Bereichen Architektur, Geschäftprozessmodellierung und Revisionssicherheit in der Softwareentwicklung. Ganz besonders interessieren ihn fachliche Themen, die eine „gewisse Würze“ haben und seine Kompetenz herausfordern.
Konatkt