Praktisches API-Design



Ähnliche Dokumente
Praktisches API-Design

API-Design für Java-Entwickler. Kai

Daniel Warneke Ein Vortrag im Rahmen des Proseminars Software Pioneers

SEP 114. Design by Contract

Einführung in die Programmierung

Objektorientierte Programmierung

Große Übung Praktische Informatik 1

Software Engineering. Zur Architektur der Applikation Data Repository. Franz-Josef Elmer, Universität Basel, HS 2015

Client-Server-Beziehungen

Java: Vererbung. Teil 3: super()

Javadoc. Programmiermethodik. Eva Zangerle Universität Innsbruck

Tagesprogramm

Objektorientierte Programmierung

Design by Contract with JML

Vererbung & Schnittstellen in C#

Testen mit JUnit. Motivation

Praktikum Datenbanksysteme. Ho Ngoc Duc IFIS - Universität zu Lübeck

Übung 1 mit C# 6.0 MATTHIAS RONCORONI

API-Design. Do s and Don ts. Jochen Kraushaar

Typumwandlungen bei Referenztypen

Nathan Burgener. Design by Contract. Modul SWE

Factory Method (Virtual Constructor)

U08 Entwurfsmuster (II)

Allgemein: Klassen testbar machen. 5. Mocking. Mocks programmieren. Zusammenspiel von Klassen testen

Objektorientierte Programmierung. Kapitel 12: Interfaces

1. Grundzüge der Objektorientierung 2. Methoden, Unterprogramme und Parameter 3. Datenabstraktion 4. Konstruktoren 5. Vordefinierte Klassen

Java Einführung Umsetzung von Beziehungen zwischen Klassen. Kapitel 7

Verhindert, dass eine Methode überschrieben wird. public final int holekontostand() {...} public final class Girokonto extends Konto {...

Java Einführung Abstrakte Klassen und Interfaces

Ein Blick voraus. des Autors von C++: Bjarne Stroustrup Conrad Kobsch

Code-Erzeugung aus UML-Klassendiagrammen

Studentische Lösung zum Übungsblatt Nr. 7

Einführung in Javadoc

Klassenbeziehungen & Vererbung

Gebundene Typparameter

Eclipse Equinox als Basis für Smart Client Anwendungen. Christian Campo, compeople AG, Java Forum Stuttgart 2007

Lösungsvorschläge. zu den Aufgaben im Kapitel 4

Softwareentwicklungsprozess im Praktikum. 23. April 2015

Einführung in die Programmierung für Wirtschaftsinformatik

am Beispiel von JUnit

Java Entwicklung für Embedded Devices Best & Worst Practices!

Session Beans & Servlet Integration. Ralf Gitzel ralf_gitzel@hotmail.de

Universität Augsburg, Institut für Informatik Sommersemester 2005 Prof. Dr. Werner Kießling 16. Juli 2005 Dr. Alfons Huhn, Timotheus Preisinger

Info: Standard DO-178B. 5. Mocking. Zusammenspiel von Klassen testen. Allgemein: Klassen testbar machen

Javakurs zu Informatik I. Henning Heitkötter

Übungen zu Softwaretechnik

Java Kurs für Anfänger Einheit 4 Klassen und Objekte

Implementation of a Framework Component for Processing Tasks within Threads on the Application Level

Programmieren in Java

Workshop Java Webentwicklung Tapestry. Ulrich Stärk

3 Objektorientierte Konzepte in Java

Test-Driven Design: Ein einfaches Beispiel

Programmierkurs Java

Graphische Benutzungsoberflächen

Der lokale und verteilte Fall

Algorithmen und Datenstrukturen

Einstieg in die Informatik mit Java

WPF Steuerelemente Listbox, ComboBox, ListView,

Unsere Webapplikation erweitern

Software-Entwurfsmuster

Softwaretechnologie - Wintersemester 2012/ Dr. Günter Kniesel

Testen von graphischen Benutzeroberflächen. 26. Juni 2013

Software-Engineering und Optimierungsanwendungen in der Thermodynamik

Java Einführung Collections

Client-Server Beziehungen

Jetzt sollt ihr von der Vorlage der Grundversion 1.0 ein eigenes Textadventure erstellen.

Oliver Paulus, 7. Februar Spring Framework Einführung. Oliver Paulus, Was ist Spring?

Kapitel 6. Vererbung

Einführung in die Informatik: Programmierung und Software-Entwicklung, WS 14/15. Kapitel 11. Fehler und Ausnahmen 1

Informationssystemanalyse Problemstellung 2 1. Trotz aller Methoden, Techniken usw. zeigen Untersuchungen sehr negative Ergebnisse:

BIF/SWE - Übungsbeispiel

Java Einführung Packages

5. Abstrakte Klassen. Beispiel (3) Abstrakte Klasse. Beispiel (2) Angenommen, wir wollen die folgende Klassenhierarchie implementieren:

Klassenentwurf. Wie schreiben wir Klassen, die leicht zu verstehen, wartbar und wiederverwendbar sind? Objektorientierte Programmierung mit Java

Institut für Programmierung und Reaktive Systeme 25. August Programmier-Labor Übungsblatt. int binarysearch(int[] a, int x),

Technische Dokumentation SilentStatistikTool

Workshop Java Webentwicklung Einführung in Hibernate. Ulrich Stärk

Folgende Voraussetzungen für die Konfiguration müssen erfüllt sein: - Ein Bootimage ab Version Optional einen DHCP Server.

C# im Vergleich zu Java

Grundlagen der Programmierung Prof. H. Mössenböck. 3. Verzweigungen

Einführung in die Programmierung Blockkurs Java

Spec# Einführung. Formale Software-Entwicklung Seminar SS 07 Universität Karlsruhe Hilal Akbaba

Log xmllog textlog Log() start(filename) add(message) end() instance() Abbildung 7-10: Die Protokollierungs-API mit einer einfachen Fassade

MO 27. Aug. 2007, 17:00 UHR JAVA FRAMEWORKS TIPPS VON PROFI-GÄRTNERN GEGEN WILDWUCHS

4D Server v12 64-bit Version BETA VERSION

Programmierkurs Java

Grundlagen der Programmierung Prof. H. Mössenböck. 14. Schrittweise Verfeinerung

Klausur zur Einführung in die objektorientierte Programmierung mit Java

Struts 2 Das Imperium schlägt zurück?

Fortgeschrittenes Programmieren mit Java. Test Driven Development

Java-Schulung Grundlagen

Problemstellung. Informatik B - Objektorientierte Programmierung in Java. Vorlesung 24: Reflection 1. IDE und automatische Tests.

5. Abstrakte Klassen

Vorkurs C++ Programmierung

Objektorientierte Programmierung

3 Objektorientierte Konzepte in Java

Kapitel 6. Vererbung

Einführung in die objektorientierte Programmierung mit Java. Klausur am 19. Oktober 2005

Application Frameworks

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Transkript:

Praktisches API-Design Kai Spichale adesso AG 13.07.15

Eine API ist wie die Spitze eines Eisbergs.. 2 http://www.pixelio.de/media/685029

Klassische Funktionen einer API Entkopplung von Implementierung Client API Implementation Definiert Komponente durch ihre Operationen mit Ein- und Ausgabewerten Softwarewiederverwendung und Integration 3

Kommunikationsproblem bei Softwarewiederverwendung? Lösung: Kommunikation durch API > APIs werden für Menschen geschrieben > Perspektive ist beim API-Design entscheidend 4

Für wen ist API-Design relevant? 5

Entwurf 6

Empfohlene Vorgehensweise Anwendungsfälle Klein mit den wichtigsten Anforderungen beginnen API häufig schreiben Regelmäßiges Feedback Feedback API schreiben 7

Qualitätsmerkmale 8

Qualitätsmerkmale Konsistent Intuitiv verständlich Dokumentiert Einprägsam und leicht zu lernen Führt zu leicht lesbarem Code Minimal Stabil Einfach erweiterbar Grundvoraussetzung: Nützlich und korrekt :-) 9

Konsistent Konzeptionelle Integrität bedeutet kohärentes Design mit der Handschrift eines Architekten 10

Konsistent java.util.zip.gzipinputstream java.util.zip.zipoutputstream java.awt.textfield.settext(); java.awt.label.settext(); javax.swing.abstractbutton.settext(); java.awt.button.setlabel(); java.awt.frame.settitle(); 11

Intuitiv verständlich Idealerweise ist Client-Code ohne Dokumentation verständlich Vorwissen ausnutzen und bekannte Konzepte wiederverwenden Starke Begriffe etablieren und diese konsequent wiederverwenden 12

Java Collection API java.util.list add addall contains containsall remove removeall java.uilt.set add addall contains containsall remove removeall java.util.map put putall containskey, containsvalue - remove - 13

Dokumentiert Gute Dokumentation ist unverzichtbar 14

Dokumentationsaufbau 15

16 Entwickler lernen und verstehen mit Beispielen

Einprägsam und leicht zu lernen Einflussfaktoren > Konsistenz, Verständlichkeit und Dokumentation > Größe (Anzahl der Konzepte) > Vorwissen der Benutzer > Time to First Hello World 17

Führt zu leicht lesbaren Code EntityManager em =...; CriteriaBuilder builder = em.getcriteriabuilder(); CriteriaQuery<Order> cq = builder.createquery(order.class); Root<Order> order = cq.from(order.class); order.join(order_.positions); cq.groupby(order.get(order_.id)).having( builder.gt(builder.count(order), 1)); TypedQuery<Order> query = em.createquery(cq); List<Order> result = query.getresultlist(); 18

Führt zu leicht lesbaren Code EntityManager em =...; QOrder order = QOrder.order; JPQLQuery query = new JPAQuery(em); List<Order> list = query.from(order).where(order.positions.size().gt(1)).list(order).getresults(); 19

Schwer falsch zu benutzen new java.util.date(2015, 7, 9); int year = 2015 1900; int month = 7-1; new java.util.date(year, month, 9); 20

Minimal Hinzugefügte Elemente können nachträglich nur schwer entfernt werden Im Zweifel Elemente weglassen Trade-off: Minimalität vs. Komfort > Gut: java.util.list.removeall() > Schlecht: java.util.list.removealleven() 21

Minimal Auslagerung in Hilfsklassen > z.b.: java.util.arrays, java.util.collections Performance und Nebenläufigkeit > putifabsent() wäre in separater Hilfsklasse nicht threadsicher Optionale Methoden und Konstruktoren kennzeichnen > z:b.: java.io.printwriter enthält convenience Text 22

Stabil API-Änderungen sollten nur mit Sorgfalt durchgeführt werden Client Client Client Vertrag API v1 23

Einfach erweiterbar Welche Änderungen wird es in Zukunft geben? Erweiterung idealerweise abwärtskompatibel, sonst neue API-Version notwendig Anpassungsaufwand für Clients minimieren 24

Abwärtskompatibilität 25

Kompatibilität Trade-off: Abwärtskompatibilität vs. Flexibilität Code-Kompatibilität Schwächste Form der Kompatibilität Konflikte beim Entfernen und Verändern von API-Elementen Konflikte eventuell bei Vererbung 26

Kompatibilität class ApiBaseClass { /** * @since 1.1 */ List<String> getresults() {... } } class MyOwnClass extends ApiBaseClass { List<ResultItem> getresults() {... } } 27

Kompatibilität Binär-kompatibel: Programm kann neue Version ohne erneute Kompilierung verwenden Beispiel: > Kompilieren mit log4j 1.2.15 > Linken gegen log4j 1.2.17 Grundvoraussetzung: Dynamisches Linken > Einsprungadresse von virtuellen Methoden wird zur Laufzeit bestimmt 28

Funktionale Kompatibilität Version kann gelinkt werden und erfüllen ihre erwartete Funktion Erwartetes Verhalten Tatsächliches Verhalten Tatsächliches Verhalten der neuen Version 29 Bekannt als Amöben-Effekt (Jaroslav Tulach)

Versionierte Regressionstests! 30

Design-Repertoire 31

Erzeugungsmuster Factories und Builder statt Konstruktoren entitymanager.createnamedquery(queryname).getresultlist(); CalculatePriceCommand.new(order).run(); Vorteil Verwendung unterschiedlicher Subtypen Erzeugung komplexer Objekte vereinfachen Keine Konstruktoren mit vielen Parametern 32

Effective Java 2nd Edition Static Factory, statt Konstruktoren nutzen 33

Alternative: Class Clusters 34

Beispiel: Class Cluster public class Widget { private Widget body; public Widget(boolean b) { } if (b) { body = new WidgetA(); } else { body = new WidgetB(); } } public void performaction() { } body.performaction(); } 35

Vererbung Kontroverse Ansätze: > Open Inheritance > Designed Inheritance Standardmäßig alle konkreten Klassen final machen > Vererbung verletzt Datenkapselung > Klassen müssen speziell für Vererbung entworfen werden > Für Wiederverwendung Kompositionen nutzen Beispiele: > Richtig: Set extends Collection > Falsch: OrderPositionSet extends Set<OrderPosition> 36

Template-Methode abstract class OrderSorter { public void sort(list<order> orders) { if(compare(o1, o2)) { } abstract compare(order o1, Order o2); } 37

API versus SPI Application Programming Interface Wird von Benutzern aufgerufen z.b.: FileSystem API, FileObject Methoden können i.d.r. hinzugefügt werden Service Provider Interface Wird durch Client-Code implementiert (Callback durch Framework) z.b.: java.sql.driver muss von jedem JDBC-Treiber implementiert werden Neue Methoden brechen Client-Code 38

Template-Methode public class OrderSorter { private final Comparator<? super Order> comp; public OrderSorter(Comparator<? super Order> comp) { } this.comp = comp; public void sort(list<order> orders) { } Collections.sort(orders, comp); } 39

Kontextobjekt als Parameter für SPI Schlechter Stil: public interface MyServiceProviderInterface { void callbackmethod(string param); } Besser: public interface ServiceProviderInterface { void callbackmethod(context param); } public class Context { String message(); Integer id(); } 40

Methoden mit Destruktorsemantik Beispiele JUnit: @Before, @After JDBC: Belegen und Freigeben von Ressourcen Reihenfolge beachten! Evtl. Ressourcen in umgekehrter Reihenfolge freigeben 41

Interface-Evolution Hinzufügen einer neuen abstrakten Methode war vor Java 8 eine inkompatible Änderung interface NewInterface extends OldInterface { void newmethod(); } Ab Java 8 Default-Methoden Bevorzuge Klassen vor Interfaces 42

Checked Exceptions void submit( Abstract abstract ) throws IOException {... } Falsches Abstraktionsniveau 43

Checked Exceptions Kann diese Ausnahmesituation im korrekten Programm auftreten? void submit( Abstract abstract ) throws TooLongAbstractException {... } Kann sich ein Client davon erholen? Sparsam einsetzen! 44

Unchecked Exceptions Gehört eine Unchecked Exception zur API? void submit( Abstract abstract ) { if( abstract == null ) { throw new NullPointerException( "abstract must not be null."); }... } 45

Unchecked Exceptions /** * * @throws NullPointerException * if abstract is null */ void submit( Abstract abstract ) { if( abstract == null ) { throw new NullPointerException( "abstract must not be null."); }... } Dokumentiere alle Exceptions, die von einer Methode geworfen werden (Vorbedingungen). 46

Invarianten und Bedingungen Klassen sind selbst für die Einhaltung ihrer Invarianten verantwortlich (nicht Client) Klassen sollten ihre Vorbedingungen möglichst gut überprüfen Nachbedingungen werden mit Tests überprüft 47

Immutability / Minimale Änderbarkeit Klassen, die public und konkret sind, sollten standardmäßig final und immutable sein Vorteile: > Thread-safe > Wiederverwendbar > Einfach Nachteile: > Separates Objekt für jeden Wert Falls änderbar, dann sollte Zustandsraum klein sein 48

Sinnvolle Defaults Vermeidung von Boilerplate-Code Geringe Einstiegshürden und Unterstützung für Neueinsteiger Boolean sind standardmäßig false (entsprechende Namen wählen) Defaults müssen dokumentiert sein 49

Globaler Zustand / Konfiguration Globaler Zustand ist problematisch weil: > Schwer testbar, nicht flexibel > Fehleranfällig, schwer verständlich Empfehlung: > Sei funktional, vermeide Zustand > Einbindung einer Bibliothek sollte keine Änderungen des globalen Zustand notwendig machen > Falls doch, dann ist es eine Applikation und keine Bibliothek Beispiel: > Log4j wird beim Laden automatisch konfiguriert > Unterschiedliche Konfigurationen für Log4j in einem Prozess nicht möglich 50

Empfehlung: Vorträge von Joshua Bloch 51

Kai Spichale @kspichale http://spichale.blogspot.de/ https://www.xing.com/profile/kai_spichale 52