Entwicklungsumgebungen

Entwicklungsumgebungen sind die Schweizer Taschenmesser der Softwareentwicklungstools. Ihr Sinn besteht darin, möglichst alle Werkzeuge, die der Entwickler braucht, in einer Oberfläche zu bündeln - daher auch der englische Name Integrated Development Environment (IDE). Sie verbinden einen Texteditor mit einer Projektverwaltung und in der Regel weiteren Werkzeugen wie Versionskontrollsystemen und Refactoring-Tools. IDEs glänzen dadurch, dass sie Debugger (siehe Kapitel 13) besonders komfortabel einbinden: Man kann ein Programm schreiben und auf Knopfdruck im Debugger starten, um seine Funktion zu überprüfen.

Diese Kombination erleichtert das Programmiererleben ungemein. jedenfalls dann, wenn man sich erst einmal in eine Entwicklungsumgebung eingearbeitet hat. Bis es so weit ist, investiert man aber Zeit und Nerven. Denn eines haben fast alle Entwicklungsumgebungen gemeinsam: Ihre Bedienung lässt sich nicht an einem Nachmittag erlernen.

Man kann das am eindrucksvollsten an der sehr weit verbreiteten Open Source-Umgebung Eclipse sehen. Sie wurde als eierlegende Wollmilchsau der Softwareentwicklung konzipiert und bildet daher nur das Gerüst für eine in jede Richtung erweiterbare und konfigurierbare IDE. Die eigentliche Funktionalität wird durch Plugins hergestellt, also Erweiterungen. Man kann sich diejenigen herunterladen, die Unterstützung für die verwendete Programmiersprachen oder Frameworks bieten, und sich so eine maßgeschneiderte Umgebung zurechtlegen. Eclipse ist daher für die Entwicklung in nahezu allen Programmiersprachen nutzbar, und darüber hinaus auch als HTML-Editor.

Projektverwaltung

Viele Entwicklungsumgebungen organisieren Sourcecode in Projekten. Man kann daher den Code für verschiedene Programme mit derselben lDE verwalten, ohne dass sich die Dateien ins Gehege kommen, denn jede ist in ein bestimmtes Projektschächtelchen sortiert - und nur in eines. Selbst wenn Sie in den verschiedenen Projekten gleichnamige Dateien angelegt haben, weiß die Entwicklungsumgebung, welchem Projekt welche Datei zugeordnet ist. Das ist zunächst nicht so überraschend - jedes Projekt ist im Dateisystem als ein Verzeichnis abgelegt, die Software organisiert die Projektdateien also auch nicht anders, als man das selbst tun würde.

Zusätzlich legt die Software für jedes Projekt noch Informationen darüber ab, was benötigt wird, um aus dem Code ein lauffähiges Programm zu machen. Das ist von Sprache zu Sprache sehr unterschiedlich, es kann im Falle eines C++-Programms ein Compiler- und ein Linkerlauf sein, im Fall einer Java-Enterprise-Anwendung muss ein JAR-Archiv erzeugt oder ein Webserver gestartet werden. Es gibt auch Entwicklungsumgebungen für Webanwendungen, die entweder einen lokalen Webserver starten oder die Dateien per SSH auf einen Server hochladen können. Und bei Mobile-Anwendungen kommt zum Kompilieren noch das Signieren und das Hochladen auf einen Emulator oder ein Smart-phone dazu. All das wird projektweise spezifiziert und in einer >>Build Configuration« gebündelt. Wenn Sie Ihr Programm in seiner fertigen Form exportieren wollen, klicken Sie auf einen >>Build«-Knopf, und schon setzt sich die Maschine im Inneren der Entwicklungsumgebung in Gang und arbeitet alle Schritte zum Produkt ab.

Entwicklungsumgebungen können für die von ihnen verwalteten Programme weiterhin Abhängigkeiten verwalten; das bedeutet, dass Sie angeben, welche Bibliotheken oder Frameworks Sie für ein Programm verwenden wollen, und die Entwicklungsumgebung Ihnen die entsprechenden Dateien zu der jeweiligen Build Configuration hinzufügen kann. Häufig können Entwicklungsumgebungen dazu Paketmanager (siehe den Abschnitt >>Paketmanager« weiter oben in diesem Kapitel) wie Maven oder Bower einbinden: Sie suchen direkt in der IDE aus einer Liste von Bibliotheken die gewünschte aus und legen die benötigte Version fest, und die IDE lädt die Datei herunter. Das ist recht praktisch, wenn Sie testweise eine neuere Version einer Bibliothek verwenden wollen: Sie können nämlich in der IDE die benötigte Versionsnummer ändern, und das Programm lädt die neue Version runter und kompiliert Ihr Programm, und Sie können sehen, ob der Versionssprung zu Compiler- oder Laufzeitfehlern führt.

Codechecker

Der tägliche Workflow eines professionellen Programmierers sieht meistens so aus: Code aus dem Versionskontrollsystem auschecken, Programmieren, Refakturieren, Testen,

Änderungen ins Versionskontrollsystem einchecken. Genau das wird durch IDEs erleichtert. Wer bei dem Begriff »professioneller Programmierer« das Buch zur Seite legen möchte, sei getröstet: Die Werkzeuge, die eine IDE mitbringt, sind für alle nützlich, auch für die, die gerade seit gestern nicht mehr über das »hallo« von »Hallo Welt<<-Program-men nachdenken müssen.

Entwicklungsumgebungen bringen einen Sprachparser mit Syntaxchecker mit, der Code noch während des Schreibens auf syntaktische Korrektheit hin prüft (siehe Abbildung 20-3). Der Editor versteht die Syntax der jeweiligen Sprache und markiert sofort fehlerhaften Code. Das spart Zeit, da Sie die Datei mit dem fehlerhaften Code nicht erst kompilieren oder auf einen Server hochladen müssen, um Fehler zu bemerken. (Der Fairness halber sei angemerkt, dass alle besseren Texteditoren wie emacs, vim, Sublime Text etc. das auch können.)

Inspction Rt.suits for ln$pJ)«tion Profile 'Projtct Oefauif -    • Lop statement ttet doesn't

assets

'for' Statement doesn't looo css

«j ▼ Dat.a flow issues re'Tls |

• Redundant loeal variable assets

OLocalvariable 'z' ts redundant O Local variable color' is redundant

X Pl

i fr

Nane

diagraas.js

Location

file jj

t

4- y*

jl ? \s * ?

Probls synopsis

Local variable ' text ’ is redundant

General

HTML

Suppress

Suppress for Statement

Abbildung 20-3: Code-TÜV bei der Arbeit

In statisch typisierten Sprachen (siehe Kapitel 26) wie Java kann die IDE auch überprüfen, ob Sie gerade einer Funktion, die eine Zahl als Input erwartet, eine Datei, einen String oder sonst einen falschen Typ als Variable übergeben wollen. In Abbildung 20-4 gibt Eclipse den freundlichen Hinweis, dass in Java keine automatische Typumwandlung von Strings nach Zahlen stattfindet und Sie daher eine Stringvariable nicht mit einer Zahl multiplizieren dürfen.

public void LestMethod(Stnng input) {

int wrong - \np.vt|Jt;

^    43The operator is undefined for the argurr.ent type(s) String, int

Press f2 r

Abbildung 20-4: Java mag keine Strings multiplizieren

Entwicklungsumgebungen können Code markieren, der zwar nicht fehlerhaft, aber unsauber ist und sogenannte Warnings produziert. Der markierte Code wird dann in einer »Problems«- oder »Warnings«-Liste geführt. Kleinere Codeprobleme wie vergessene Semikolons am Zeilenende oder überflüssige NULL-Tests treten immer mal auf und können in hektischen Zeiten toleriert werden, sie haben aber die Eigenschaft, sich unter ungünstigen Umständen zu echten Fehlern auszuwachsen. Eine Entwicklungsumgebung, die den Benutzer zu manierlicher Programmierung erzieht, hilft späteres Leid vermeiden.

Codevervollständigung

Während Sie einen Texteditor einfach öffnen und sofort losprogrammieren können, müssen Sie in Entwicklungsumgebungen Ihre Arbeit in Projekten organisieren. Die Entwicklungsumgebung weiß dann für jedes Projekt genau, welche Sprache oder Sprachen Sie verwenden werden, welche Frameworks und welche Bibliotheken. Von diesem Wissen ausgehend, macht sie auf Wunsch Vorschläge zur Codevervollständigung (siehe Abbildung 20-5).

public vo 1 d setSpinnerSelection(String selection) { this.fflSclectl.on - selection;

g' ecti.on.

}

protected KCTh £isenheinr

9 substrmgOnt start) String $ substrmgOnt start. int end) String • toCharArravO char(l

Strin<

Herotor<K • toLolherCa.seO String wh i h (i le e toLowerCasedoca.le locale): String String KCThre # toStrmgO . String f ( t. $ tolJpperCaseO Strmg

re • toUpperCase(Locale locale) Su rg trimO String

Si g

Abbildung 20-5: Codevervollständigung in Eclipse

Das Beispiel zeigt einen Ausschnitt aus einem Java-Programm. selection ist eine lokale Variable vom Typ String. Die auf dieser Variable aufgerufene Codevervollständigung weiß, welche Methoden Strings in Java mitbringen, und zeigt sie als Codevorschläge an. Da Java eine stark typisierte Sprache ist, kann die IDE auch angeben, wie viele Parameter welchen Typs jede Methode erwartet und was der Rückgabewert der jeweiligen Methode ist (siehe Abbildung 20-6).

pubt ic dass Bol iseCroupLrrorMessoge extends ConfigurobleDSEMessage {

public Bo'. iseGroupCrrorMessage (byte^ i nDota, DSEMessogeDcfim l\on conftgurotion, T’ super (inData, configuralion, timelone);

}

public int getN!D_C_UNlSIG () { try {

n*t. CRSeI

t CachingDSEMessageCbytefl inData, TimeZone timeZone) - de.isnow.etcs.data.dse.mes $ ConflgurableDSEMessage(byte(| inData. DSEMessageDefimtion conhguration, TimeZor # ConhguraöleDSCrieldODSEDefimtionField def)

W ConhguraöleDSEfieldODSEDehnitionField def. int id)    ’

Abbildung 20-6: Kurzschreibung in Eclipse

Vorteile von Entwicklungsumgebungen

Das ist für mich wahrscheinlich das Feature, weswegen ich Entwicklungsumgebungen wirklich mag: einen Variablennamen tippen, einen ».<< dahinter und dann schauen, was mit dem Objekt so alles geht. Wenn ich dann sehe, da kommt nichts, dann weiß ich, ich habe irgendwo im Programm einen Fehler drin und sollte mich da erst mal drum kümmern. Das ist Kurzreferenz, Debugging-Hilfe und Arbeitsbeschleunigung in einem Feature. Und Weiterbildung nicht zu vergessen: >>Ach schau, das kann das Objekt also auch noch.«

Das stimmt mich selbst grauenhaft lieblosen Produkten wie Oracle SQL Developer, einer IDE für Datenbankprogrammierung, gewogen. Gerade wenn man in einer eher heterogenen Umgebung mit vielen verschiedenen Standards für die Benennung von Spalten in einer Tabelle arbeitet, ist es so praktisch, nur »USER.« zu tippen und dann zu sehen, ob die Primary-Key-Spalte ID oder USER_ID heißt. Außerdem ist jeder Typ, jede Variable und jede Funktion ein Hyperlink, und man kann sich ganz leicht zur Definition durchklicken.

Johannes

Verwandt damit ist ein Vorschlagssystem, das es erlaubt, eine Kurzform eines Variablentyps zu schreiben.1 Die IDE kann aufgrund der Abkürzung den gesuchten Typ erraten und anzeigen: CDSE wird zu ConfigurableDSEMessage. Das funktioniert besonders gut in Sprachen, die gerne lange Typnamen haben und diese im CamelCase schreiben. Man schreibt dann die Anfangs- und ein paar der Binnenmajuskeln hin und lässt den Typnamen expandieren. In Sprachen ohne explizite Typen, wo Variablen alle den Typ var haben, ist diese Unterstützung natürlich deutlich weniger wert.

Unterstützung der Arbeitsorganisation

Viele Entwicklungsumgebungen bringen Features mit, die die Programmiererin in ihrer Arbeitsorganisation unterstützen. Hierzu gehört die Einbindung von Versionskontroll-systemen (VCS). Zwar kann man problemlos nach jeder größeren Änderung aus dem Texteditor in die Desktopumgebung oder ein Terminal wechseln, um dort die letzten Änderungen in das Versionskontrollsystem einzuchecken, aber wenn man erst einmal einen Wechsel aus der Codeumgebung gemacht hat, liegt es nahe, kurz mal auf reddit zu schauen, wie sich die Katzenmerne-Situation entwickelt - und schon hat man den Faden verloren (siehe Abbildung 20-7).

Daher können Sie in einer Entwicklungsumgebung ein ganzes Projekt, ein Teilprojekt oder eine einzelne Datei wählen und ins Versionskontrollsystem einchecken, auf den Stand des VCS zurücksetzen oder die Änderungsliste betrachten. Das ist nichts, was nicht auch ohne IDE ginge, aber die Einbindung ist nahtlos.

• *• Bayeux tackend . . Bibber Wbisam 'LJ BrdinBrowscr ^CarnLccch QContentPuser UCurlstocks ^ DachsParser O de.tcamspnng.ar LJj de teamspnng.ar Udetcamsprmg ar L0erby

LLJDIA-Test 1. DIA Tool ^DIAGrep L,.:jOSBrowsei

rtammm

   ' src

•    it * net.kraut 1 iß • net.kraut

•- nct krautch

•    net .krautcl'l

..    nct xrautch

.. tfi net kravtch

•    •• nct itrautcl'l

•    iß net . xrautch p iß net krautch

•    »gcn

.. B< A!1drod Oepei

•    §fc Refcrenced Ufc

assets

bin

liöi

»,’■ res

•    stuff Andro dManlft1

L Lesestof'f.txt hnt.xml , NOTICE.txt ‘'I' proguard .cfg

Eiscnbemrii

Google Web Toolkit

s SaliseGrouptrrorMessogc utends Conf

New

SoliscGroupCrrorlolcssogc (byte[J tnüott

Go Into

er (tnDoto, configurotion, timelonc);

Open in New Window

•nt gelNlO_C_UNlSlG () {

Open Type Hierarchy

F4

{

Show ln XW

11

return ( tnt)getFicldVa'lue0yNa:m:c("NiD. atch (txcepbon cx) {

Copy

XC

ex pri.nLStackTraceO,

Copy Qualified Name

Paste

XV

t' Commit... X#

liC Delete

Fetch from Upstream " Push to Upstream

trr^rnt Context

3

Build Path

Remote ►

Source \:XS

Switch To 11

Refactor \:XT

Advanced •

• Import.. .

H ■ PuII

gi' Export...

’ Synchronize Workspace

Find Bugs

Mh^

Refresh

F5

Close Project

Merge...

Close Unrelated Projects

Reset. ..

Assign Working Sets...

Rebase...

Run As

11

Create Patch...

Debug As

Apply Patch...

Profile As

f*

Validate

h lgnore ,

Compare With Replace With

Restore from Local History.. Google Andro1d Tools Configure

Properties

XI

Add to lndex Remove from Index 61 Untrack

fjhShow in Repositones Vtew Show in History

Disconnect

Abbildung 20-7: Einbindung von Git Eclipse

TODOs können in Kommentaren notiert werden - je nach Sprache beispielsweise so:

//TODO Error handling omitted for row

Und die IDE kann einem eine saubere Liste aller TODOs präsentieren. Auf Knopfdruck. Wenn man beispielsweise den Bauch voll hat vom Mittagessen und nicht zu echten kreativen Leistungen fähig ist, kann man sich dann dem Abarbeiten dieser Liste widmen. Ähnliche Listen gibt es auch für Fehler und Warnungen.

In Entwicklungsumgebungen sind Variablennamen und -typen häufig Hyperlinks. Man kann auf den Variablennamen klicken und der Texteditor springt zu ihrer Definition. Noch praktischer bei Variablentypen: Wenn man auf sie klickt, wird die Datei geöffnet, in der sie definiert sind. Auch dieser Vorteil wirkt sich nur in stark typisierten und objektorientierten Sprachen aus, weil nur hier zur Programmierzeit klar ist, welchen Typ eine Variable hat. Bei schwach typisierten und dynamischen Sprachen wie PHP oder Perl kann die IDE das nicht bestimmen.

Suchen und Refactoring

lDEs sind machtvolle Werkzeuge für die Programmierung und Pflege von Code. Wer einmal mit dem globalen Suchen-und-Ersetzen eines Variablennamens ein Projekt verwüstet hat, der weiß zu schätzen, dass die Entwicklungsumgebung Code versteht. Man kann mit ihrer Hilfe gezielt den Namen einer Variablen ändern, ohne dass dadurch die Namen von gleichlautenden Funktionen und Inhalte von Konstanten mitverändert werden. Stellen Sie sich vor, Sie wollen die Variable username in folgendem Codeabschnitt durch user_id ersetzen:

const prompt = "Please enter your username"

var username = get_username();

Dann wollen Sie wahrscheinlich nicht den String verändern, der im UI verwendet wird, möglicherweise auch nicht den Funktionsnamen, sondern nur den Variablennamen. Das wäre mit Suchen und Ersetzen schwierig, aber da die Entwicklungsumgebung den Unterschied zwischen der Variable, dem Funktionsnamen und der Stringkonstante versteht, kann sie Ihnen sehr helfen. Die integrierte Suche kann häufig auch zwischen »Suche in Funktionsnamen« und »Suche in Kommentaren« unterscheiden - das macht die Ergebnisse deutlich nützlicher.

lst eine Datei zu lang geworden, dann muss man ihre einzelnen Bestandteile wie Variablen, Funktionen oder inneren Klassen mühsam herauskopieren und auf neue Dateien verteilen. Danach muss man sicherstellen, dass die neuen Module genauso importiert werden wie das bisherige, das unhandlich wurde. Und dann muss man im Code noch prüfen, welche Änderungen man nachziehen muss. Mit einer Entwicklungsumgebung ist es möglich, einen Codebereich oder eine innere Klasse zu markieren und sie automatisch in eine neue Datei zu verschieben. Alle Referenzen werden von der IDE automatisch nachgezogen. Zu groß gewordene Dateien in kleinere zu zerschlagen, verliert durch diese Hilfestellung deutlich an Schrecken.

Nachteile

Entwicklungsumgebungen gewinnen niemals Usability-Preise und haben eigentlich immer ein vollkommen überladenes User-Interface, in dem Knöpfe für wichtige Tasks wie »Kompiliere und starte das Programm« neben seltener benötigten wie »Neue C-Datei<< angebracht sind. Wegen dieser fehlenden Benutzerfreundlichkeit und weil sie einen ungeheuer großen Funktionsumfang bieten, können sie auf weniger geübte Nutzer abschreckend wirken. Die Visual-Studio-Express-Produkte von Microsoft sind unter den traditionellen Entwicklungsumgebungen eine positive Ausnahme. Eclipse als das Open Source-Flaggschiff ist leider ein gutes Beispiel für schlechtes Oberflächendesign. Die Firma JetBrains stellt für verschiedene Sprachen Entwicklungsumgebungen her, die zwar hässlich, aber ziemlich gut durchdacht und hilfreich sind.

Weitere Nachteile sind folgende:

•    Sie müssen erst einmal eine Entwicklungsumgebung finden und installieren. Das ist langweilig und unter Umständen schwierig. Eine Suche nach >>IDE<< und dem Namen der Programmiersprache sollte einige Links zum Vorschein bringen, unter denen Sie dann auswählen können.

•    Als Nächstes kommt die Einarbeitung. Da der Funktionsumfang groß und die Benutzerschnittstellen eher schlecht sind, ist die Lernkurve steil. Das ist ungünstig für den blutigen Anfänger, der sich dann gleichzeitig mit den Problemen der neuen Sprache und der Lernkun'e der IDE beschäftigen muss.

•    Schlechte Angewohnheiten werden von einer IDE nur zu einem ganz kleinen Teil erkannt und korrigiert. Sie können problemlos auch innerhalb einer IDE miserablen Code schreiben.

•    Zwar können Sie zwischen verschiedenen lDEs auswählen, sind dann aber auf die Eigenheiten dieser Umgebung festgelegt. Dadurch, dass eine Entwicklungsumgebung die verschiedenen Werkzeuge integriert, fährt man am besten, wenn man mit der vorgesehenen Werkzeugkiste auskommt. Wer bei lKEA mit den 5 vorgegebenen Billy-Farben nicht klarkommt, wird vermutlich ohne IDE zufriedener leben. Er wird sich seine Arbeitsumgebung dann mit Terminal Co. direkt an die eigenen Bedürfnisse anpassen und keine Kompromisse machen müssen. Wer einen faulen Kompromiss längerer Konfiguration vorzieht, sollte sich Entwicklungsumgebungen zumindest anschauen.

Vielleicht verspüren Sie eine diffuse Abneigung dagegen, an Ihrer derzeitigen Werkzeugsituation etwas zu ändern. Es ging doch bisher auch so! Dagegen ist nichts einzuwenden. Betrachten Sie dieses Kapitel, wie man fremder Leute Heimwerkerkeller betrachtet. Sie haben jetzt zumindest schon einmal von der Existenz der hier beschriebenen Tools und einigen Anwendungsmöglichkeiten gelesen. Eines Tages kommt vielleicht der Moment, an dem Sie das Gefühl haben, beim Lösen des aktuellen Problems könnte Ihnen eines davon weiterhelfen.

Erfahreneren Programmierern ergeht es nicht wesentlich anders als Ihnen: Egal, wie viel man weiß, es gibt immer noch mehr Werkzeuge und Strategien, von denen man noch nie auch nur gehört hat. Erfahrenere entwickeln nur im Laufe der Zeit ein Gespür dafür, bei welcher Art von Problemen man auf die Existenz einer fertigen Lösung oder eines hilfreichen Tools hoffen kann. Sie haben Strategien, diese Lösungen aufzuspüren und im Alltag nebenbei zu verfolgen, was gerade neu hinzukommt. Und sie sträuben sich manchmal etwas weniger stark als unerfahrene Programmierer dagegen, ihre Arbeitsabläufe zu verändern, wenn eine solche Veränderung Vorteile verspricht.

1

Das folgende Beispiel stammt aus einer objektorientierten Sprache. In diesen Sprachen kann man seine Variablentypen in Form von Objekten selbst definieren, so wie in den Beispielen in Kapitel 23 die Typen Article, Pnglmage oder Customer.