Entwicklungsdetails

Die wichtigste Aufgabe der Softwareentwicklung besteht darin, die Vision eines Softwarearchitekten in einen funktionierenden Anwendungscode umzusetzen. Dieser Code sollte die geforderten Ergebnisse erzielen, unter den definierten Bedingungen reibungslos funktionieren, stabil und sicher sein und innerhalb der angegebenen Parameter ausgeführt werden können. Diese Ziele sollten allesamt mit optimaler Effizienz und bestmöglichem Einsatz der verfügbaren Ressourcen erreicht werden. Das mag nach einer schwierigen Aufgabe klingen. Dank moderner Softwareentwicklungstechniken, Tools, Entwicklungsumgebungen und Methoden können Teams jedoch Software erstellen, mit der sie sich der Aufgabe in logischer und strukturierter Herangehensweise nähern können. So lässt sich die Erfolgsquote maximieren und unnötiger Aufwand minimieren.

Die Fähigkeiten in der Softwareentwicklung

Während sich ein schlechter Anfangsentwurf zwar nur schwerlich in gute Software umsetzen lässt, so können Architekten, Designer und Entwickler doch auf viele Tools und Techniken zurückgreifen, die die Wahrscheinlichkeit, einen gelungenen Entwurf zu einer ausgezeichneten Software weiterzuentwickeln, deutlich erhöhen. Entwickler müssen sich zwar an die Entwurfsspezifikationen halten, doch zu ihren Aufgaben gehört auch die Fähigkeit zu visualisieren, wie Arbeitssysteme und Komponenten interagieren, und zu erkennen, welche Grenzen durch die Hardware und die Infrastruktur, auf der die Anwendungen ausgeführt werden, auferlegt werden. Außerdem müssen sie fundierte Beurteilungen der erforderlichen Kompromisse vornehmen.  

Das bedeutet, dass das Wissen um die Verwendung einer Programmiersprache wie C# oder Visual Basic nicht ausreicht. Moderne Programmierframeworks und -sprachen stellen virtualisierte Schnittstellen zur Verfügung, die die zu Grunde liegende Komplexität der Laufzeithardware weitestgehend verbergen. Entwickler müssen dennoch verstehen, wie Code ausgeführt wird, wie verschiedene Programmieranweisungen mit der zugrunde liegenden Infrastruktur interagieren und wie die Kommunikation zwischen Komponenten, die miteinander harmonieren müssen (zumeist bei Remote-Standorten oder bei Zugriff über ein Netzwerk wie z.B. das Internet), implementiert werden.

Das Ziel eines guten Softwareentwurfs ist in der Regel die Maximierung verschiedener wichtiger Faktoren wie Sicherheit, Nutzbarkeit, Prüfbarkeit, Wartbarkeit und Leistung. Entwickler müssen durchschauen, inwieweit sich ihre Implementierungen des Entwurfs auf diese Faktoren auswirken. Sie müssen darauf vorbereitet sein, zur Erreichung der geeigneten Kompromisse für jeden einzelnen Faktor mit dem Architekten oder dem Softwaredesigner zusammenzuarbeiten.

Programmiersprachen

Beim Schreiben von Software stehen zahlreiche Sprachen zur Auswahl. Einige beziehen sich auf bestimmte Anwendungstypen, andere hingegen können für die meisten Anwendungen eingesetzt werden. Beim eigenständigen Arbeiten wird häufig die Sprache bevorzugt, mit der die größte Vertrautheit für eine breite Palette von Anwendungstypen besteht. Bei der Arbeit im Team wird die Auswahl der Sprache im Allgemeinen von den Projektmanagern vorgegeben.

Für einige Anwendungen ist unter Umständen jedoch mehr als eine Programmiersprache oder -technologie erforderlich. Ein Beispiel hierfür ist die Webentwicklung. Hier kann der Code, der auf dem Webserver zum Erstellen der Seiten ausgeführt wird, ASP.NET Web Forms oder WebMatrix-Webseiten verwenden. Die Seiten selbst enthalten unter Umständen JavaScript-Code, der im Browser des Benutzers zur Bereitstellung von Interaktivität ausgeführt wird. Der Backend-Code, der mit der Datenbank interagiert, kann wiederum in einer .NET-Sprache wie C# oder Visual Basic geschrieben sein.

Dies bedeutet, dass Sie häufig mehrere Sprachen beherrschen müssen. Dies ist nicht allzu schwierig, da die meisten Sprachen einen ähnlichen Ansatz zum Definieren von Quellcodeanweisungen verwenden und sich hauptsächlich in der Syntax unterscheiden. Jede Sprache verfügt jedoch über spezifische Nuancen, mit denen Sie sich vertraut machen müssen. Sobald Sie jedoch die Grundlagen des Programmierens verstanden und eine Sprache erlernt haben, fällt das Erlernen anderer Sprache wesentlich leichter.

Heute werden die meisten Anwendungen mit objektorientierten und ereignisgesteuerten Programmiersprachen geschrieben. Diese Programmiersprachen verwenden Codeanweisungen und Konstrukte wie Schleifen und Entscheidungsanweisungen zum Ausführen von einer Reihe von Aufgaben. Sie enthalten Prozeduren und Funktionen, die vom Hauptcode aufgerufen werden, und zwar häufig wiederholt von verschiedenen Positionen im Code. Objekte werden innerhalb des Codes definiert, um reale Elemente wie Kunden, Aufträge und Konten, die der Code bearbeiten muss, darzustellen.

Diese Objekte verfügen über Eigenschaften, die die in den Objekten enthaltenen Daten verfügbar machen, sowie über Methoden, die zur Datenbearbeitung ausgeführt werden können. Objekte lösen Ereignisse aus, wenn eine bestimmte Aktion eintritt. Diese Ereignisse werden vom Code wie erforderlich verarbeitet. Typische objektorientierte und ereignisgesteuerte Programmiersprachen, die auf der Microsoft-Plattform verwendet werden, sind C#, Visual Basic, C++, F# und JavaScript.

Frameworks, Codebibliotheken und Muster

Einer der Schlüsselfaktoren bei der Vereinfachung der Aufgabe, die heute erforderlichen, zunehmend komplexen Anwendungen zu entwickeln, ist die Verwendung von Frameworks, Codebibliotheken und Muster. Das wiederholte Schreiben desselben Codes erfreut sich keiner großen Beliebtheit, denn es ist repetitiv und kostet Zeit und Aufwand. Daher ziehen es Entwickler vor, sich auf die Teile des Entwicklungsprozesses zu konzentrieren, die im Hinblick auf die Anforderungen der Anwendung, die sie erstellen, unmittelbar relevant sind. Eine Möglichkeit, dies zu erreichen und gleichzeitig Zeit, Kosten und Aufwand zu minimieren, ist die Wiederverwendung von vorhandenem Code, der bestimmte vordefinierte Aufgaben ausführt.

Wiederverwendbaren Code gibt es in vielen Formen. Entwicklungsteams erstellen häufig Bibliotheken mit Funktionen und Prozeduren, die sie in mehr als einer Komponente und mehr als einer Anwendung einsetzen. Typische Beispiele sind Funktionen zum Implementieren der Protokollierung, zur Behandlung von Ausnahmen, zum Zwischenspeichern von Daten und zum Zugreifen auf Datenbanken. Außerdem besteht die Möglichkeit, Frameworks und Codebibliotheken, die diese und viele verschiedene andere Aufgaben ausführen, zu beziehen oder zu erwerben. Das Wiederverwenden von Code, der bereits getestet wurde und sich als zuverlässig bewährt hat, kann den zum Erstellen von Software erforderlichen Aufwand erheblich reduzieren. Es liegt in der Kompetenz des Entwicklers zu wissen, welche Frameworks geeignet sind und wann und wie sie erfolgreich anzuwenden sind.

Wenn keine wiederverwendbaren und vorab erstellten Frameworks oder Bibliotheken verfügbar sind, muss das Entwicklungsteam den erforderlichen Code schreiben. Außerdem muss das Entwicklungsteam den Bindecode (Glue Code) schreiben, der die Komponenten zusammenhält und Funktionen in Frameworks und Codebibliotheken aufruft. Hierfür sind fundierte Kenntnisse der Programmiersprachen erforderlich. Es gibt jedoch noch eine andere Möglichkeit, in der Sie von der Arbeit anderer profitieren können, auch wenn kein physischer Code verfügbar ist. Diese Möglichkeit besteht in der Anwendung von Softwaremustern.

Muster stellen ein Konzept dar, das zur Formalisierung der Kenntnisse und der Erfahrungen entwickelt wurde, die im Laufe der Zeit beim Lösen allgemeiner Probleme bei der Softwareentwicklung zusammengetragen wurden. Szenarien, die eine Codelösung erfordern, wurden von anderen bereits mehrfach bearbeitet, und eine optimale Lösung auf der Grundlage von Berichten und Erfahrungen der Experten in dem entsprechenden Fachbereich wurde entwickelt. Diese Szenarien werden in Form von Softwareentwurfsmustern dokumentiert und umfassen allgemeine Definitionen der Lösung, die sich nicht auf einen bestimmten Sprachcode beziehen. Stattdessen bieten sie bewährte Verfahren zur Lösung des Problems. Die Aufgabe des Entwicklers besteht nun darin, in Erfahrung zu bringen, ob relevante Muster vorhanden sind, und Code zu schreiben, der für seine Anwendung spezifisch ist, jedoch auf der allgemeinen durch das Muster beschriebenen Lösung basiert. Dadurch lassen sich Fehler minimieren und allgemeine Fehler vermeiden, die in jedem einzelnen Szenario vorkommen.

Programmiertechniken und -methoden

Selbst äußerst erfahrenen Entwicklern können beim Schreiben von Code Fehler unterlaufen. Komplexe Anwendungen enthalten viele Variablen. Code, der richtig zu sein scheint, kann unter bestimmten Bedingungen, die beim Schreiben des Codes nicht offensichtlich waren, zu unerwarteten Ergebnissen führen. Im Laufe der Zeit sind Techniken und Methoden, die dazu beitragen, Fehler zu minimieren, entstanden und wurden formalisiert. Sie sollten mit diesen Techniken und Methoden vertraut sind, auch wenn Sie nicht im Team, sondern eigenständig arbeiten.

Eine der wichtigsten heute verwendeten Methoden ist TDD (Test Driven Design). Diese Methode zielt darauf ab, den Entwickler anzuregen, zunächst über die Anforderungen des Codes nachzudenken und die erforderlichen Ergebnisse zu formulieren, bevor er den eigentlichen Code schreibt. Der Prozess umfasst das Erstellen einer Reihe von Komponententests. Bei jedem dieser Tests wird eine bestimmte Funktion des Entwurfs für den Abschnitt des zu erstellenden Codes ausgeführt. Wenn der Code beispielsweise eine Zahlung auf das Konto eines Kunden vornimmt, würde im Rahmen des Tests der Zahlungsbetrag und der aktuelle Kontostand an die Funktion im erstellten Code weitergegeben werden und anschließend durch Überprüfen des Kontostands die Richtigkeit des Ergebnisses bestätigt werden.

Komponententests werden zuerst geschrieben. Anschließend wird der Code erstellt, der die in der Anwendung erforderlichen Funktionen implementiert. Dieser Code kann dann verifiziert werden, indem ein Testframework (oder eine Testumgebung) zum Ausführen aller Komponententests und zum Anzeigen der Ergebnisse sämtlicher Assertionen verwendet wird. Beim Schreiben des Codes und seiner fortlaufenden Modifizierung und Verbesserung können die Tests erneut ausgeführt werden, um sicherzustellen, dass die Ergebnisse nach wie vor gültig sind.

Natürlich funktionieren die Komponententests nicht mit den realen Daten und können unter Umständen nicht auf andere Teile der Anwendungen, die noch im Aufbau sind, zugreifen. Stattdessen erstellt der Entwickler Mock-Komponenten, die das reale Objekt repräsentieren, jedoch lokal auf dem Entwicklungscomputer ausgeführt werden. Dadurch wird sichergestellt, dass die Tests nur den erstellten Code ausführen und die Ergebnisse nicht durch externe Faktoren beeinflusst werden.

TDD wird häufig mit anderen Programmiermethoden kombiniert. Beispielsweise wird Pair Programming im Allgemeinen zum Validieren des Codes und zum Minimieren von Fehlern verwendet. Zwei Entwickler arbeiten dabei an einem Computer und wechseln sich beim Schreiben von Code und Ausführen der Komponententests ab. Die Entwickler geben dabei eigene Erfahrungen und Kenntnisse weiter und kombinieren beides. Außerdem wird konstruktive Kritik an dem vom anderen Entwickler geschriebenen Code geübt. Die zusätzlichen Beiträge und der Wettbewerb zwischen den beiden Entwicklern kann einen besseren Code hervorbringen.

Testen, Staging und Bereitstellen

Der während der Entwicklung erstellte Code stellt häufig nur ein Abschnitt der gesamten Anwendung oder des Systems dar. Er muss daher in regelmäßigen Abständen in die vollständige Anwendung bzw. das System integriert werden, um sicherzustellen, dass keine Interaktionsprobleme zwischen den einzelnen Komponenten oder den einzelnen Codeabschnitten auftreten. In der Regel wird der Code dazu in regelmäßigen Abständen überprüft. An diesem Punkt wird ein vollständiger Build der Anwendung bzw. des System initiiert. Dadurch werden Konflikte während der Kompilierungs- und der Testphase aufgedeckt. Diese müssen vor dem nächsten integrierten Build behoben werden.

Nachdem die vollständige Anwendung erstellt wurde und den Testzyklus passiert hat, kann sie zur Durchführung eines abschließenden Akzeptanztests auf einen Staging Server oder Computer verschoben werden. Im Gegensatz zum Entwicklungscomputer und zu den Build Servern handelt es sich beim Staging Server um ein Replikat der endgültigen Laufzeitumgebung. So kann die Software unter Bedingungen getestet werden, die auch während der Produktion vorliegen. Wieder muss das Entwicklungsteam alle Probleme beheben, die während des Akzeptanztestzyklus auf dem Staging Server auftreten.

Für Anwendungen ist üblicherweise ein Installations- oder Setup-Programm erforderlich, mit dem sie sowohl auf dem Staging- als auch auf dem endgültigen Produktionssystem bereitgestellt werden können. Das Entwicklungsteam erstellt das erforderliche Setup-Programm, mit dem die Komponenten der Anwendung installiert und konfiguriert werden, die Laufzeitumgebung konfiguriert und das System nach Bedarf vorbereitet wird. Häufig handelt es sich hierbei um eine komplexe Angelegenheit, insbesondere für Shrink Wrap-Software, die auf den verschiedensten Laufzeitplattformen mit einer breiten Palette zugrunde liegender Hardware oder mit anderen vorhandenen Anwendungen installiert wird.

Arbeit im Projektteam

Die Arbeit in einem Projektteam kann sehr lohnenswert sein, erfordert jedoch zusätzliche Fähigkeiten, um die besten Ergebnisse zu erhalten. Bei der Arbeit im Team müssen Entwickler in der Lage sein, gut mit zahlreichen anderen Personen zu kommunizieren und zu interagieren. Dies umfasst Managementteams, Architekten und Designer, Testteams, Dokumentationsteams und viele andere.

Verschiedene Arten des Projektmanagements verlangen Entwicklern unterschiedliche Fähigkeiten ab. Einige Projekte werden als herkömmliches "Wasserfallmodell" ausgeführt, bei dem jede Aufgabe aufgegliedert und abgeschlossen wird, bevor die nächste Aufgabe beginnt. Projekte werden jedoch zunehmend auf einer ausgesprochen interaktiven Basis ausgeführt. Diese Basis hat sich in vielen Szenarien der Anwendungsentwicklung als vorteilhaft erwiesen.

Ein Projekt wird beispielsweise mit der agilen Methodik durchgeführt, bei der kurze Entwicklungsiterationen, tägliche Besprechungen und wöchentliche Prüf- und Iterationsplanungsbesprechungen eingesetzt werden, damit das Projekt nach Plan läuft. Im Mittelpunkt der agilen Entwicklung stehen die Beiträge des Kunden und der externen Beteiligten durch regelmäßige Softwareversionen während der Entwicklung und durch kontinuierliches Feedback. In der Regel wird ein Repository mit Arbeitsaufgaben verwendet, damit das Projekt nach Plan läuft. Es gibt jedoch keinen größeren Vorabentwurf mit Ausnahme des Entwurfs, der erforderlich ist, um das Projekt in Gang zu bringen.       

Ein anderer gängiger Ansatz besteht im Extreme Programming (XP). Bei diesem Ansatz wird die Entwicklung der Software durch Implementierung der wichtigsten Anforderungen im ersten Schritt, kontinuierliche Kommunikation und Tests und regelmäßige Bereitstellung der Software während der weiteren Entwicklung gefördert. Sowohl die agile Methodik als auch XP heben die Erstellung der Arbeitssoftware gegenüber dem Vorabentwurf hervor und konzentrieren sich auf die Erzielung der Ergebnisse, die den Erwartungen entsprechen, statt auf die Entwicklung unnötiger Features. Dies bedeutet, dass die Teammitglieder produktiv sein müssen und effizient, strukturiert und kontrolliert arbeiten müssen, um die wöchentlichen Aufgaben zu erledigen. Außerdem müssen sie gut mit den anderen Beteiligten des Prozesses kommunizieren.

Die zwischenmenschliche Kommunikation ist ein wichtiger Faktor in modernen Softwareentwicklungsteams. Sie ist am einfachsten und in der Regel am produktivsten, wenn das Team im selben Gebäude oder gar im selben Teambüro arbeitet. Geografisch verstreut angesiedelte Teams arbeiten erfahrungsgemäß dann gut zusammen, solange die einzelnen Personen die Kommunikation mit anderen Teammitgliedern gut meistern. Besprechungen werden mit Telefon- und Videokonferenzsoftware abgehalten, das Informationsrepository ist über das Internet verfügbar und die Teammitglieder halten strenge Zeitpläne für tägliche und wöchentliche Besprechungen ein. Dazu müssen die einzelnen Mitglieder sich an Zeitzonenbeschränkungen anpassen und effizient mit anderen Teammitgliedern verschiedener Nationalitäten interagieren. Außerdem müssen sie die Kommunikationssysteme so nutzen, dass es für alle Teammitglieder leicht ist, eine vollwertige Rolle zu spielen.

Lernen und Erfahrungen

In kaum einer anderen Branche ändern sich die Technologien, Methoden und Arbeitsumgebungen so rasant wie in der IT-Welt. Große Bau- und Maschinenbauprojekte dauern häufig mehrere Jahre, während selbst große Softwareanwendungen eine Projektdauer bezogen auf Entwurf, Entwicklung und Bereitstellung von weniger als einem Jahr und häufig deutlich darunter haben. Gleichzeitig ändern sich die verfügbaren Tools, Frameworks, Infrastrukturen und Technologien sehr rasant, mitunter sogar von Jahr zu Jahr.

Dies bedeutet, dass der Entwickler Zeit für die Änderungen einplanen muss, indem er sich über neue Techniken, Programmiersprachen und andere technologischen Fortschritte informiert. Außerdem ist ein Verständnis für die Trends in der sich wandelnden IT-Welt erforderlich. Der Entwickler muss berücksichtigen, wie sich diese Trends auf die heute entwickelte Software auswirken. Ferner muss er in der Lage sein, seine eigenen Programmierfähigkeiten anzupassen, um den Einsatz dieser neuen Fähigkeiten zu optimieren.

Von allen Fähigkeiten des Entwicklers wird der Erfolg am meisten von der Erfahrung beeinflusst. Und diese lässt sich nur im Laufe der Zeit erwerben. Die Arbeit im Team, die Interaktion mit anderen Entwicklern und die Fähigkeiten auf dem neuesten Stand zu halten stellen grundlegende Anforderungen dar. Diese Anforderungen in Kombination mit einem Gespür für logisches Denken, Kreativität und einem Hang zum Perfektionismus machen das ideale Fähigkeitenset für einen Softwareentwickler aus.