API-Design. Kai SpichaleЧитать онлайн книгу.
Mit wenigen Seiten anfangen
Den Entwurf einer API sollte man mit einem Umfang von zunächst nur wenigen Seiten beginnen. Denn nicht jeder Kollege, den man um Feedback bittet, hat Zeit und Lust ein hundertseitiges Dokument zu lesen. Ein kurzer Entwurf kann außerdem auch leichter verändert werden. Agilität ist am Anfang wichtiger als Vollständigkeit.
3.4Wenn Use Cases nicht ausreichen
Use Cases sind eine etablierte Technik zur Ausarbeitung von Benutzeranforderungen. Use Cases dokumentieren die Vereinbarungen zwischen den Beteiligten eines Projektes über das Verhalten des geplanten Systems. Das Verhalten des Systems ist die Reaktion auf das Handeln eines Hauptakteurs, der ein bestimmtes Ziel verfolgt. Für jeden Use Case werden deswegen Szenarien für die Verwendung des Systems entwickelt. Ein Use Case ist relativ abstrakt und fasst mehrere Szenarien, die dieselben Ziele betreffen, zusammen.
Man kann Use Cases formlos schreiben, häufig werden auch Templates verwendet. Alistair Cockburn empfiehlt eine kurze informelle Variante (casual version) und eine stark strukturierte Variante (fully dressed version) [Cockburn 2000]. Wem keine der beiden Varianten gefällt, kann diese für sein Projekt anpassen. Man sollte in jedem Fall sicherstellen, dass Use Cases ein Ziel haben, einfach zu lesen sind und nicht zu viele Schritte enthalten.
Use Cases vermitteln Entwicklern ein allgemeines Verständnis über das beabsichtigte Verhalten des Systems. Allerdings brauchen Entwickler mehr Informationen als in Use Case enthalten sind. Aus diesem Grund ist neben den Use Cases auch eine Anforderungsspezifikation (software requirements specification) notwendig, die die funktionalen und nicht funktionalen Anforderungen detaillierter beschreibt.
Use Cases sind ungeeignet für beispielsweise Hardwareprodukte mit Steuerungssoftware, für Data-Warehouse-Projekte, Datenverarbeitung mit Batch-Jobs und andere komplexe Datenverarbeitungssoftware. Denn in den genannten Beispielen ist die Komplexität in den Berechnungsalgorithmen verborgen. Der Gebrauch der Software, die mit den Use Cases dargestellt wird, ist im Vergleich dazu trivial. Die Use Cases können in diesen Fällen die für Entwickler interessanten Informationen nicht beschreiben.
Eine wichtige Alternative sind die Event-Response-Tabellen [Wiegers 2006]. In Abhängigkeit des Zustandes des Systems reagiert das System auf ein Ereignis mit einer bestimmten Reaktion oder Antwort. Ereignisquellen sind beispielsweise Sensoren, zeitbasierte Trigger oder Benutzeraktionen.
3.5Entwurf mit Szenarien und Codebeispielen
Hilfreich zum Entwurf einer API sind Beispiele, die die Verwendung der API aus Clientperspektive zeigen. Als Grundlage für diese Beispiele sind repräsentative Anwendungsszenarien geeignet.
Kommunikation zwischen Client und API beschreiben
Die Kommunikation zwischen Client und API kann zu Beginn mit Interaktionsbeispielen beschrieben werden. Man sollte Notationen verwenden, mit denen man gut arbeiten kann. Es müssen keine formal korrekten UML-Sequenzdiagramme sein. Auch einfache Skizzen auf einem Whiteboard eignen sich gut für diese Aufgabe. Die Entwürfe können dann mit Kollegen oder Teammitgliedern diskutiert und gemeinsam verbessert werden. Wenn Sie die API einer Bibliothek entwerfen, können Sie diesen Schritt auch überspringen.
Szenarien mit Code aufschreiben
Im zweiten Schritt folgen bereits Codebeispiele für die Benutzung der API entsprechend den Anwendungsszenarien. Viele objektorientierte Ansätze beginnen mit dem Entwurf des Objektmodells und schreiben die Beispiele für die resultierende API danach. Eine API, die mit einem derartigen Bottom-up-Ansatz entsteht, spiegelt häufig die Struktur der internen Implementierung wider und ist schwerer zu benutzen. Beginnen Sie stattdessen den Entwurf der API mit einem Top-down-Ansatz aus der Perspektive der späteren API-Benutzer. Die API wird nur dann gut, wenn sie für die wichtigen Benutzungsszenarien optimiert wird.
Schreiben Sie die Codebeispiele entsprechend der Priorität der Szenarien, sodass die wichtigsten Szenarien am elegantesten mit der API zu lösen sind. Nutzen Sie die Programmiersprachen und Technologien der späteren API-Benutzer.
Es ist wichtig, eine API früh und häufig mit Beispielen auszuprobieren.
Angenommen Sie wollen die API eines Audit-Logs entwerfen, das Benutzerinteraktionen speichert, um eventuellen Missbrauch einer Anwendung feststellen zu können. Die Codebeispiele für die Szenarien des Audit-Logs könnten folgendermaßen lauten:
// Szenario 1: Erfolgreiche Benutzeranmeldung loggen
AuditLogger logger = new AuditLogger();
AuditEvent event = logger.event()
.name("user login")
.status(SUCCESS)
.user("user1")
.date(new Date())
.build();
logger.log(event);
// Szenario 2: Fehlgeschlagene Benutzeranmeldung loggen
AuditLogger logger = new AuditLogger();
AuditEvent event = logger.event()
.name("user login")
.status(FAILURE)
.user("user1")
.date(new Date())
.detail("failure explanation", "wrong password")
.detail("user locked", "true")
.build();
logger.log(event);
Zur Erzeugung der AuditEvent-Instanzen könnten Sie beispielsweise mit verschiedenen Erzeugungsmustern experimentieren und deren Vor- und Nachteile abwägen. Die Beispiele helfen Ihnen außerdem, eventuelle Entwurfsfehler frühzeitig zu erkennen. Erst wenn Sie eine API mehrfach auf diese Weise geschrieben haben, sollten Sie weitere Details spezifizieren oder mit der Implementierung beginnen. Aus den Codebeispielen ergibt sich folgendes API-Design für das AuditLog:
public class AuditLogger {
public AuditLogger() { }
public AuditEventBuilder event() { }
public void log(AuditEvent event) { }
}
public class AuditEventBuilder {
public AuditEventBuilder name(String name) { }
public AuditEventBuilder status(String success) { }
public AuditEventBuilder user(String user) { }
public AuditEventBuilder date(Date date) { }
public AuditEventBuilder detail(String key, String value) {
}
public AuditEvent build() { }
}
public class AuditEvent {
// Getter-Methoden
}
Die Codebeispiele sind die Grundlage für eine szenariobasierte API-Spezifikation. Diese kann Teil einer größeren Spezifikation sein oder in einem separaten Dokument abgelegt werden. Die geschriebenen Beispiele können als Teil der Spezifikation, als ausführbare Dokumentation und für Testzwecke verwendet werden.
3.6Spezifikation erstellen
Nachdem die Klassen und Interfaces der zu entwerfenden API mithilfe der Codebeispiele identifiziert worden sind, könnte eine formale Spezifikation erstellt werden. API-Spezifikationen dieser Art werden beispielsweise im Rahmen des Java Community Process