Ich verwalte derzeit eine Bibliothek, die viel öffentlich genutzt wird, und ich hatte eine Frage zur semantischen Versionierung . Ich möchte einen ziemlich wichtigen Teil der Bibliothek umgestalten, der falsch implementiert ist - und immer falsch implementiert wurde. Dies würde jedoch Änderungen an der öffentlichen API bedeuten, was eine wichtige Entscheidung ist.
Die Änderung, die ich vornehmen möchte, dreht sich darum, wie Iteratoren verwendet werden. Derzeit müssen Benutzer dies tun:
while ($element = $iterator->next()) {
// ...
}
Was zumindest in der nativen Iterator-Oberfläche von PHP nicht stimmt . Ich möchte Folgendes ersetzen:
while ($iterator->valid()) {
$element = $iterator->current();
// ...
$iterator->next();
}
das ist analog zu:
foreach ($iterator as $element) {
// ...
}
Wenn Sie sich Toms Handbuch zur semantischen Versionierung ansehen, stellt er klar, dass alle Änderungen an der öffentlichen API (dh diejenigen, die nicht abwärtskompatibel sind) eine Hauptversion rechtfertigen sollten. Die Bibliothek würde also von 1.7.3 auf 2.0.0 springen, was für mich ein Schritt zu weit ist. Wir sprechen nur über ein Feature, das repariert wird.
Ich habe vor, irgendwann 2.0.0 herauszubringen, aber ich dachte, dies war der Zeitpunkt, an dem Sie die Bibliothek komplett neu geschrieben und zahlreiche öffentliche API-Änderungen vorgenommen haben. Ist für die Einführung dieses Refactorings eine Hauptversion erforderlich? Ich kann wirklich nicht sehen, wie es funktioniert - ich fühle mich wohler, wenn ich es als 1.8.0 oder 1.7.4 veröffentliche. Hat jemand einen Rat?
next()
Methode verwendet, um das aktuelle Element abzurufen UND den internen Zeiger vorwärts zu bewegen. Was falsch ist.next()
sollte den Zeiger bewegen, undcurrent()
wird verwendet, um abzurufen ...next()
nur dem kümmern, der den Zeiger bewegt, das bricht wirklich nicht die KompatibilitätAntworten:
Sie zögern, weil Sie keine semantische Versionierung vornehmen möchten, sondern "Werbung zur Unterstützung der Versionierung". Sie erwarten, dass die Versionsnummer "2.0" der Welt mitteilt, dass Ihre Bibliothek eine Reihe neuer cooler Funktionen enthält, und nicht, dass Sie die API geändert haben. Das ist in Ordnung (viele Softwareunternehmen und / oder Entwickler machen das). IMHO haben Sie folgende Möglichkeiten:
next
, sondern fügen Sie einfach die Funktionenvalid
und hinzucurrent
). Dann können Sie "1.8.0" als nächste Versionsnummer verwenden. Wenn Sie der Meinung sind, dass das Ändern des Verhaltens vonnext
wirklich wichtig ist, führen Sie es in 2.0.0 aus.quelle
next()
, das zu tun, was es tut. Um die Funktionalität korrekt zu implementieren, muss etwas anders gemacht werden. Wenn ich es also abwärtskompatibel mache, ist die neue Funktionalität / Korrektur ebenfalls falsch und untergräbt den gesamten Punkt der Änderung.next()
Methode gehackt , um alle neuen Funktionen zu nutzen, und auch, was erforderlich war, um die Abwärtskompatibilität zu gewährleisten. Es fühlt sich irgendwie schrecklich an, neue Funktionen wie diese trüben zu müssen, aber hey ho.Halten Sie sich an Toms Leitfaden zur semantischen Versionierung.
Jede wesentliche Änderung an einer öffentlichen API muss an einem der beiden Punkte vorgenommen werden:
Meine Stimme ist übrigens für die erste. Aber ich gebe zu, dass es nur für Kleinigkeiten geeignet ist.
Das Problem besteht darin, die Abwärtskompatibilität aufrechtzuerhalten und sicherzustellen, dass die vorherigen Benutzer Ihrer API keine Probleme haben.
Im Wesentlichen erstellen Sie einen Indizierungsfehler für Ihre Benutzer, die die Änderung nicht kennen. Wenn Sie eine solche Änderung erzwingen, müssen alle Benutzer die folgenden Schritte ausführen:
Dies kann möglicherweise eine Menge Aufwand bedeuten, insbesondere wenn Sie berücksichtigen, wie wenige Projekte Testfälle haben, um solche Änderungen zu validieren. Der Aufwand ergibt sich aus der Anzahl der nachgeschalteten Benutzer Ihrer Benutzer, deren Installationen ebenfalls aktualisiert werden müssen.
Für etwas so Kleines würde ich es loslassen und mich nicht darum kümmern.
Wenn es dich wirklich stört (was es anscheinend tut oder du nicht gefragt hättest), dann würde ich folgendes tun.
Release Notes
bevor Sie die Änderung bekannt gebenUnd dann haben Sie etwas Geduld, denn es wird eine Weile dauern, bis Sie andere Dinge gefunden haben, die ein Upgrade der Versionsnummer auf eine neue Hauptversion rechtfertigen. Die erweiterte Benachrichtigung (Teil 3) gibt Ihnen Zeit, Feedback von Endbenutzern zu erhalten, um herauszufinden, wie stark sich die Änderung auswirken wird.
Eine alternative Lösung besteht darin, eine neue Funktion hinzuzufügen, die wie gewünscht funktioniert.
Wenn ja
foo()
, würden Sie erstellenfooCorrect()
, um das Update bereitzustellen, aber auch die Abwärtskompatibilität vollständig zu erhalten. Und irgendwann können Sie es ablehnenfoo()
, wenn andere wissen, dass Sie es nicht verwenden sollen.Die Herausforderung besteht, dass Sie finden etwas anderes in
fooCorrect()
dem erfordert es das Update und Sie am Ende mitfooCorrectedCorrect()
oder einigen anderen Dummheiten.Wenn Sie dies jetzt wirklich korrigieren möchten , ist dieser alternative Ansatz wahrscheinlich die beste Route. Seien Sie sich bewusst und seien Sie vorsichtig, wenn Sie auf diese Weise viele zusätzliche Funktionen erstellen, da dies die Arbeit mit der API erschwert. Und dieses Bewusstsein könnte ausreichen, um die schlimmsten Probleme dieser Art zu verhindern.
Dies könnte jedoch der "am wenigsten schlechte" Ansatz sein, der für etwas Kleines in Betracht gezogen werden sollte.
quelle
next()
nichtnextCorrect()
). Ich werde sehen, ob ich next () so modifizieren kann, dass es abwärtskompatibel ist UND bei der Implementierung derIterator
Schnittstelle funktioniert .