Ob im Tagesjob oder für eigene Projekte, welche Abhängigkeiten (Module, Gems, libs, …) für Projekte gewählt wurden hat einen massiven Einfluss auf die spätere Entwicklung und besonders die Instandhaltung der Software. Während ich mir zu Beginn dazu kaum Gedanken gemacht habe, ist mittlerweile fast schon ein Regelwerk im Kopf entstanden. Teils aus der Mischung der positiven und den schmerzhaft negativen Erfahrungen, teils aus offiziellen Regeln für Qualitätskriterien auf der Arbeit.
So denke ich derzeit:
0. Ist die Abhängigkeit notwendig?
Die oberste Direktive für Notwendigkeit ist Aufwandsminimierung. Nur wenn sie insgesamt Aufwand minimiert kann eine Abhängigkeit positiv wirken. Also nur wenn sie etwas umsetzt, was mit eigenen Code nicht gegangen wäre oder viel Arbeit gekostet hätte. Entsprechend ist die erste Frage, ob die Abhängigkeit funktionell sinnvoll und wie notwendig sie ist.
Warum diese Aufwandsperspektive? Weil jede Abhängigkeit potentiell Folgearbeit bedeutet. Wann immer eine neue Version herauskommt, die Anpassungen am eigenen Code einfordert, muss nur wegen der Abhängigkeit Arbeit investiert werden. Und das ist dann praktisch immer verlorene Arbeitszeit, die das Projekt an sich nicht weiterbringt. Aber es kann auch andersherum sein: Wenn durch die Einbindung einer Abhängigkeit eine stete Folgearbeit ausgelagert werden kann, wie die Anpassung an eine sich immer wieder ändernde API, spricht viel für die Einbindung. Das Szenario ist aber selten.
Ein Beispiel für diese Überlegungen ist der MF2-Parser, den wir für Webmentions in Serendipity eingebunden haben. Da war ich am Zögern, ob so viel fremder Code notwendig ist, könnte man das HTML doch auch auf anderem Wege parsen. Aber der offizielle MF2-Parser ist im Zweifel exakter und vermeidet dann Arbeit, wenn sonst der eigene Code für die verschiedenen Webmention-Formate immer wieder angepasst werden müsste. Er war auch der empfohlene Weg der Umsetzung, daher schlug ich seine Einbindung vor.
Die Erwartungshaltung der benötigten Folgearbeit variiert hier stark je nach Entwicklungssprache und dann nochmal je nach Nische innerhalb der Sprache, ist sie groß genug. Um ein paar Erfahrungswerte zu teilen: Javascript samt Node ist berüchtigt für die kurze Halbwertszeit und den wahnsinnigen geforderten Aufwand; bei Flutter beziehungsweise Dart gab es da noch keine etablierte Kultur, sondern variierte es wohl je nach Entwicklerhintergrund; Module für Ruby und PHP (hier im Gegensatz zur Sprache selbst) sind normalerweise respektvoll.
1. Welche Abhängigkeiten hat die Abhängigkeit?
Es empfiehlt sich einen Blick auf die Abhängigkeiten der Abhängigkeit zu werfen. Je mehr das sind, desto eher können durch sie neue Probleme entstehen. Ob das Interaktionen mit dem eigenen Code sind oder, wahrscheinlicher, wegbrechende oder sich ändernde Projekte Probleme verursachen, die dann über die Abhängigkeit an das eigene Projekt weitergegeben werden.
2. Wie beliebt ist die Abhängigkeit?
Die Beliebtheit kann durch das jeweilige Empfehlungssystem transportiert werden, wie die Sterne bei Github, oder durch Artikel, die das Modul vorstellen und loben. Beliebtheit ist erstmal positiv, die Weisheit der Masse wird nicht völlig unberechtigt ein Projekt hervorheben. Und viel Aufmerksamkeit kann die Chance erhöhen, dass bei einem Einschlafen der Entwicklung sich ein Nachfolgeprojekt bildet.
Gleichzeitig kann Beliebtheit negative Auswirkungen haben, wenn die Entwickler durch einen Nutzeransturm überfordert werden, die gefühlte Popularität ihnen zu Kopf steigt oder schlicht durch die Masse an Anforderungen der Projektfokus verlorengeht.
Gleichzeitig gibt es immer wieder gute Module, die von der Masse ignoriert werden. Oder das technisch bessere Folgeprojekt, das zwar beliebt ist, aber weniger als das früher etablierte. Die Inertia der Masse ist hier eben auch ein Thema. Daher ist Beliebtheit ein Faktor, aber ein schwacher.
3. Ist die Dokumentation brauchbar?
Die Brauchbarkeit der Dokumentation würde ich sehr viel höher hängen. Brauchbarkeit ist hier bewusst gewählt, statt Umfang. Ich habe mehrfach sehr umfangreiche Dokumentation erlebt, die aber überhaupt nicht hilfreich war, weil sie die aufkommenden Nutzungsfragen einfach nicht beantwortete.
Ein gutes Readme kann völlig ausreichen, solange es den Umgang mit der gebotenen API sauber erklärt. Wobei bei vielen Projekten eine ausführlichere Beschreibung der Optionen in einer dedizierten Dokumentation erstrebenswert ist.
4. Wann war das letzte Update?
Das Datum des letzten Updates bestimmt, ob ein Projekt wirklich aktiv ist oder nicht.
Das darf wieder nicht überbewertet werden. Manche Projekte sind stabil und fertig, sie brauchen nur seltene Anpassungen und das lange vergangene Datum des letzten Updates bedeutet kein brach liegendes Projekt, sondern ein stabiles. Genauso kann ein kürzliches Update und ein hohes Updateinterval auf Instabilität und fehlende Entwicklerdisziplin hindeuten. Aber es gibt hier eine gesunde Balance, die das Ideal wäre.
5. Wie viele offene Bugreports und Pullrequests gibt es?
Hier kommt es wieder stark auf den Kontext an.
Ein übervoller Bug- oder Issuetracker ist erstmal ein Alarmsignal. Blöd sind auch sich aufstauende Pullrequests. Beides zeichnet das Bild eines überforderten Projekts, bei dem Probleme der Nutzer nicht angegangen werden.
Aber man darf diesen Faktor auch nicht überbewerten. Bei einem sehr beliebten Projekt beispielsweise werden fast zwangsläufig sehr viele Nutzerberichte zu Problemen zusammenkommen, die kein Entwicklerteam der Welt alle ordentlich bearbeiten kann. Wenn trotzdem auf wichtige Beiträge geachtet wird, die Entwicklung trotzdem läuft, dann ist der volle Bugtracker fast ein gutes Zeichen: Denn dann wurde kein Bot eingesetzt, der automatisch Bugreports schließt, was immer eine feindselige Haltung zur Nutzerschaft auslöst und wichtige Berichte ungesehen verschwinden lässt.
Genauso können sich bei alten Projekten Berichte ansammeln, die nicht wirklich angegangen werden können, die aber auch nicht unpassend sind und daher lange aufbleiben. Wieder, solange die Software und die Entwicklung trotzdem läuft ist das völlig okay.
6. Wie redet der oder reden die Maintainer mit Nutzern?
Das ist fast das wichtigste: Wichtiger als der Zustand des Issuetrackers in absoluten Zahlen ist das Verhalten der Entwickler darin. Werden Nutzer für ihre Berichte abgekanzelt, oder werden sie ernstgenommen und angehört? Werden Nutzer beleidigt, ihre Bugreports ohne verständlichen Grund geschlossen, fehlt einfach Freundlichkeit und Respekt sollte man sich soweit Fernhalten wie möglich.
Dabei lohnt sich auch ein Blick darauf, wer antwortet. Eine häufige Projektkonfiguration ist der erfahrene und freundliche Originalentwickler, dem aber die Zeit fehlt, und dann gibt es eine Nummer 2, die im Bugtracker viele Anfragen beantwortet. Dem Originalentwickler gegenüber wird diese Person immer nett sein, aber es besteht dann leider die Tendenz, gegenüber Nutzern respektlos zu antworten. Wird das geduldet, und wie weit ist diese Entwicklung vorangeschritten? Das wird viel darüber verraten, ob vom Originalentwickler dem Projekt noch Aufmerksamkeit geschenkt wird.
Auch wenn man selbst in diesen Projektkommunikationsmitteln nicht aktiv teilnehmen will ist das ein wichtiger Faktor, denn es wird darüber bestimmen wie gut und verständlich Antworten auf Nutzerfragen sind, ob das Projekt Nutzungsprobleme angeht und ob bei der Weiterentwicklung der Nutzer bedacht wird. Und ein vernünftiger, freundlicher Maintainer gleicht fast alle anderen möglichen Schwachpunkte eines Projektes wieder aus, denn seine Handlungen werden mittelfristig der Einstellung gleichen.
7. Wie wurde mit inkompatiblen Änderungen umgegangen?
Der Einfluss des Maintainers kumuliert im Umgang mit Breaking Changes. Also Änderungen der Abhängigkeit, die Änderungen am eigenen Code erfordern.
Um die Wichtigkeit des Aufwandsmanagements nochmal klarzumachen hilft vielleicht diese Perspektive: Das eigene Team hat X Mann. Wieviele Leute entwickeln an all den Abhängigkeiten? Wieviele entwickeln an der Grundsprache, wenn z.B. wie bei Flutter Google hunderte oder tausende Entwickler beschäftigt? Jeweils sind es viel mehr, also kann das eigene Team die investierte Arbeit der anderen nicht kontern. Das Projekt kann nur erfolgreich sein, wenn das nicht notwendig ist, wenn eben inkompatible Änderungen vermieden werden.
Daher sind sind sie immer ein großer Negativpunkt. Aber manchmal sind Anpassungen an der Schnittstelle eines Moduls schwer zu vermeiden. Sind sie selten genug, werden die nötigen Änderungen gut erklärt und verständlich gerechtfertigt sind sie natürlich akzeptierbar. Auch hilft es, wenn die Versionsnummer nach Semantic Versioning angehoben wird, zumindest in Ökosystemen, bei denen die Updatetools darauf ausgelegt sind. Dann werden wenigstens Aktualisierungszeitpunkte samt ihren Migrationen etwas besser wählbar.
Aber alleine die Nummer korrekt anzuheben reicht eben nicht. Wenn Änderungen einfach so gemacht werden, ohne Rücksicht, ist es Zeit zu rennen. Wenn beispielsweise vorher eine Funktion auf zwei Arten aufgerufen werden konnte, und jetzt eine davon wegfällt nur weil der Maintainer das schöner findet, hat er die Bodenhaftung verloren. Klar, vereinfacht das wesentlich seinen eigenen Code und Aufwand und erklärt er es entsprechend kann auch sowas mal okay sein. Aber grundsätzlich sollte Abwärtskompatibilität eine große Priorität haben. Einfach, weil sonst Abhängigkeit um Abhängigkeit Änderungen einfordern und die verfügbare Arbeitsleistung des eigentlichen Projekts für diese Pflege aufgefressen wird.
Besonders klares Zeichen sind Sprüche wie "Ich muss mich nicht rechtfertigen", wenn bei kaputtmachenden Änderungen der Grund erfragt wird, oder wenn beim Versuch die Problematik zu erklären mit emotionaler Manipulation dem Nutzer die Schuld für das Problem gegeben wird, ein Ansprechen der Problematik zu Aggressionen führt. Beides habe ich wirklich gesehen, kürzlich erst wieder. Von solchen Projekten kann man gar nicht genug Distanz wahren.
Ein weiteres Beispiel, dass Arbeit als Entwickler auch eine soziale Komponente hat.
Man kann diese Regeln ignorieren und Glück haben, man kann ihnen folgen und trotzdem von unnötigen Änderungen gepiesackt werden. Aber ich glaube, grundsätzlich sind sie kein schlechter Ansatz und recht umfassend.
Gibt es etwas, was ich übersehen habe oder was ihr anders seht?
onli blogging am : Linksammlung 36/2024
Vorschau anzeigen