Читать книгу API-Design - Kai Spichale - Страница 23
2.2.2Intuitiv verständlich
ОглавлениеDie zweite wichtige Eigenschaft einer guten API ist intuitive Verständlichkeit. Eine intuitiv verständliche API ist in der Regel auch konsistent und verwendet einheitliche Namenskonventionen. Das bedeutet, dass gleiche Dinge die gleichen Namen haben. Und umgekehrt haben unterschiedliche Dinge auch unterschiedliche Namen. Dadurch ergibt sich eine gewisse Vorhersagbarkeit. Betrachten wir dazu ein weiteres Beispiel:
Ruby-Methoden mit Ausrufezeichen (!)
Ruby-Methoden, die mit einem Ausrufezeichen (!) enden, ändern das Objekt, auf dem sie aufgerufen wurden. Methoden ohne Ausrufezeichen am Namensende erzeugen hingegen eine neue Instanz und lassen das Objekt, auf dem sie aufgerufen wurden, unverändert.
my_string.capitalize
# Funktioniert wie capitalize, erzeugt aber keinen neuen String
my_string.capitalize!
my_string.reverse
# Funktioniert wie reverse, erzeugt aber keinen neuen String
my_string.reverse!
Nachdem Sie die Beispiele für capitalize! und reverse! gesehen haben, können Sie vermutlich das Namenspaar für »downcase« erraten.
Setter- und With-Mehoden
Für Java gibt es ebenfalls derartige Konventionen. Eine Konvention betrifft Setter-Methoden wie setName, setId oder setProperty. Setter-Methoden ändern das aufgerufene Objekt. Methoden wie with-Name, withId oder withProperty ändern das aufgerufene Objekt nicht, sondern erzeugen ein neues Objekt mit den angegebenen Werten. Das Präfix »with« wird beispielsweise von Joda-Time genutzt.
Methoden der Java-Collections
Ein anderes anschauliches Beispiel sind die Collections der Java-Standardbibliothek. Die starken Begriffe add, contains und remove wurden hier etabliert und da, wo es passt, wiederverwendet. Man findet diese Methoden einheitlich in den Interfaces List und Set. Für Map wurde leider ein anderer Name verwendet. Die Methode zum Hinzufügen von Elementen heißt dort put. Zugegeben, diese Methode hat andere Parameter und funktioniert nicht wie add von List, aber auch zwischen List und Set gibt es Unterschiede. Ein einheitliches add in allen drei Interfaces wäre vermutlich besser gewesen.
Die folgende Tabelle zeigt die Interfaces von List, Set und Map im Vergleich:
java.util.List | java.util.Set | java.util.Map |
add | add | put |
addAll | addAll | putAll |
contains | contains | containsKey, containsValue |
containsAll | containsAll | – |
remove | remove | remove |
removeAll | removeAll | – |
Die Tabelle zeigt eine gewisse Symmetrie. Denn es gibt Methodenpaare wie add und remove, addAll und removeAll etc. Die Methode remove-All scheint bei Map zu fehlen, denn diese Methode wäre das Gegenstück zu putAll. Map bietet außerdem die Methode entrySet und keySet, aber nicht die Methode valueSet. Diese Methode heißt korrekterweise values, weil die Mengeneigenschaften in diesem Fall nicht erfüllt werden kann.
Es ist wichtig, starke Begriffe in einer API zu etablieren und diese einheitlich wiederzuverwenden. Beispielsweise sollten Sie nicht Synonyme wie »delete« und »remove« innerhalb einer API beliebig mischen. Entscheiden Sie sich für einen Begriff und bleiben Sie dann dabei. Verwenden Sie Begriffe, die den Benutzern der API geläufig sind. Das Wort »erase« wäre zum Beispiel zu ungewöhnlich. Ein Java-Entwickler würde vermutlich für Dateioperationen nach »create« und »delete« als Erstes suchen. Bei Persistenzoperationen hingegen nach »insert« und »remove«.
Eine API ist intuitiv verständlich, wenn Entwickler den Clientcode der API ohne die Dokumentation lesen können. Das kann nur durch Vorwissen und sprechende Bezeichner funktionieren. Daher sollten Sie gezielt versuchen, Begriffe aus bekannten APIs wiederzuverwenden.