API-Design. Kai SpichaleЧитать онлайн книгу.
vom Webserver gelöscht, es sei denn, die Transaktion wird vorher vom Client erfolgreich beendet oder abgebrochen.
Wertekonnaszenz
Diese Form von Konnaszenz liegt vor, wenn sich mehrere Werte zusammen ändern müssen, wenn beispielsweise Client und Server sich auf bestimmte Zahlen einigen, um den Zustand von Bestellungen anzugeben. Eine Bestellung in Bearbeitung hat dann zum Beispiel den Wert 2 und eine abgeschlossene Bestellung den Wert 3.
Identitätskonnaszenz
In diesem Fall müssen mehrere Komponenten dieselbe Entität referenzieren. Angenommen die zuvor erwähnte Shopping-Anwendung besteht aus mehreren getrennten Webservices für die Verwaltung der elektronischen Einkaufswagen, für den Check-out-Prozess und für die Artikelsuche. Identitätskonnaszenz liegt vor, wenn die Webservices für Check-out und Artikelsuche denselben Einkaufswagen referenzieren müssen.
Konnaszenz gibt Ihnen das notwendige Vokabular, um die Änderbarkeit von APIs zu untersuchen und die vielfältige Kopplung zwischen Client und API zu benennen.
2.4Zusammenfassung
In diesem Kapitel haben Sie die Qualitätsmerkmale bzw. Qualitätsziele kennengelernt. Diese sind hier zusammengefasst:
APIs müssen vollständig und korrekt sein.
APIs sollten konsistent, intuitiv verständlich, dokumentiert, minimal, stabil, erweiterbar und leicht zu lernen sein. Sie sollten es Benutzern leicht machen, lesbaren Code zu schreiben. Es sollte schwer sein, sie falsch zu benutzen.
Die Änderbarkeit von APIs kann mit der Metrik Konnaszenz systematisch analysiert werden.
Im folgenden Kapitel werden Sie erfahren, wie APIs auf Basis von Use Cases und Beispielen entsprechend zuvor identifizierter Anforderungen iterativ mit Feedbackschleifen entworfen werden können.
3Allgemeines Vorgehen beim API-Design
Eine API ist für gewöhnlich das Ergebnis eines Prozesses mit vielen Iterationen. Manche APIs werden über mehrere Jahre kontinuierlich entwickelt. Jeder Schritt in diesem Prozess bietet einerseits die Chance, die API zu verbessern, und andererseits die Gefahr, die API zu verschlechtern. Aus diesem Grund stellt dieses Kapitel einen Leitfaden zum allgemeinen Vorgehen beim Entwurf von neuen APIs oder zur Erweiterung existierender zur Verfügung.
3.1Überblick
Das in diesem Kapitel beschriebene Vorgehen ist in der folgenden Abbildung dargestellt. Grundvoraussetzung für den Entwurf einer API sind deren Anforderungen und deren Rolle im Gesamtsystem. Die Anforderungen werden typischerweise mit Use Cases beschrieben. Wenn diese Informationen vorliegen, können Codebeispiele für die neue API geschrieben werden. Diese Beispiele verwenden repräsentative Szenarien, die die wichtigsten Features abdecken. Sie können die Codebeispiele später auch für Tests einsetzen, doch primär sind sie für den Entwurf gedacht.
Abb. 3–1 Allgemeines Vorgehen beim API-Entwurf mit Feedbackschleifen
Bevor Sie eine API entwerfen können, müssen Sie deren Rolle in der Gesamtarchitektur einordnen. Je nach System kann die API ein ganz entscheidender, wenn nicht sogar der entscheidende Bestandteil der Architektur sein – wenn es beispielsweise darum geht, mit der API die einzelnen Bestandteile so voneinander zu trennen, dass sie sich unabhängig voneinander weiterentwickeln können, enthält die API die Summe der wichtigen Entscheidungen.
Nachdem Sie die Klassen und Interfaces der zu entwerfenden API mithilfe der Codebeispiele in mehreren Review- und Feedbackschleifen identifiziert haben, könnten Sie eine formale Spezifikation erstellen. Falls Sie keine Programmiersprachen-API, sondern eine Web-API entwerfen, würden die Beispiele typischerweise aus HTTP-Requests und Responses bestehen.
3.2Heuristiken und Trade-offs
In sehr kleinen Projekten entsteht ein Entwurf häufig informell, während der Softwareentwickler vor seinem Computer sitzt [McConnell 2004]. Der Entwurf besteht vielleicht aus Pseudocode, der einige Klassenschnittstellen skizziert. Danach folgt schon die eigentliche Umsetzung. Für größere Projekte ist ein Entwurf jedoch sehr wichtig. Der fertige Softwareentwurf sollte durchdacht und gut strukturiert sein und alle priorisierten Anforderungen umsetzen. Doch der Prozess, der zu diesem Ergebnis führt, sieht bei Weitem nicht so ordentlich aus. David Parnas und Paul Clements bringen es auf den Punkt [Parnas & Clements 1986]:
»Die Vorstellung, dass ein Softwareingenieur seinen Entwurf in einem rationalen, fehlerfreien Weg aus den Anforderungen ableitet, ist ziemlich unrealistisch. Kein System ist jemals auf diese Weise entwickelt worden, und wahrscheinlich wird das auch nie passieren. Selbst die Entwicklung kleiner Programme in Lehrbüchern und Artikeln sind unrealistisch. Sie wurden überarbeitet und aufpoliert, bis der Autor uns gezeigt hat, was er beabsichtigte, und nicht, was tatsächlich geschah.«
Daher muss man akzeptieren, dass »die erste Version niemals perfekt ist« [Tulach 2008]. Fast jedes Programm muss im Verlauf der Zeit weiterentwickelt werden, weil sich Anforderungen ändern. Wichtige Anforderungen in der Vergangenheit können morgen ungültig sein. Es könnte auch sein, dass Benutzer eine API für Aufgaben einsetzen, für die sie ursprünglich nicht konzipiert wurde.
Aus diesem Grund ist das in diesem Kapitel beschriebene Vorgehen eine Heuristik und kein deterministischer Algorithmus, den Sie Schritt für Schritt abarbeiten können, um sicher zum bestmöglichen Ergebnis zu gelangen.
3.3Anforderungen herausarbeiten
Bevor man über eine mögliche Lösung nachdenken kann, muss man erst einmal wissen und verstehen, wie die Anforderungen lauten. Systematisch ermittelte Anforderungen minimieren das Risiko, das falsche System zu bauen. Anforderungen sind häufig verborgen unter mehreren Schichten aus falschen Annahmen, Missverständnissen und politischen Entscheidungen. Anforderungen können nicht einfach eingesammelt werden, sie müssen ausgegraben werden [Hunt & Thomas 1999].
Vorgaben kritisch hinterfragen
Anforderungen sind noch keine Lösungen, wenngleich vermeintliche »Anforderungen« implizite technische Lösungen oder Einschränkungen enthalten können. Diese Vorgaben müssen kritisch hinterfragt werden, um bessere technische Lösungen finden zu können.
Anforderungen verständlich und genau formulieren
Anforderungen sollten einfach und verständlich formuliert sein, um Missverständnisse von vornherein zu vermeiden. Genauigkeit ist ebenfalls wichtig: Eine Aussage wie »Die Schnittstelle muss intuitiv und einfach verständlich sein« ist nicht hilfreich, weil »intuitiv« nicht quantifizierbar ist. Die Anforderung »Die Schnittstelle muss fehlerfrei sein« ist nicht realisierbar, denn nicht triviale Software enthält immer Fehler. Auch Anforderungen wie »Die Software läuft mit der neuesten Java-Version« sind zu ungenau, weil beispielsweise nicht klar ist, ob das SDK oder das JRE gemeint ist.
Kompromisse fair verteilen
Kompromisse müssen gemacht werden, wenn Anforderungen unterschiedlicher Benutzergruppen in Konflikt zueinander stehen. Es ist empfehlenswert, in solchen Fällen die Abstriche gleichmäßig auf alle Benutzer zu verteilen, sodass jeder eine Lösung erhält, mit der er arbeiten kann, obwohl sie für niemanden