В настоящее время я управляю библиотекой, которая широко используется, и у меня возник вопрос о семантическом версионировании . Я хочу провести рефакторинг одной довольно важной части библиотеки, которая реализована неправильно - и всегда была реализована неправильно. Но это будет означать изменения в публичном API, что является важным решением.
Изменение, которое я хочу сделать, вращается вокруг того, как используются итераторы. В настоящее время пользователи должны сделать это:
while ($element = $iterator->next()) {
// ...
}
Что неверно, по крайней мере, в родном интерфейсе итератора PHP . Я хочу заменить на это:
while ($iterator->valid()) {
$element = $iterator->current();
// ...
$iterator->next();
}
что аналогично:
foreach ($iterator as $element) {
// ...
}
Если вы посмотрите на руководство Тома по семантическому версионированию, он ясно заявляет, что любые изменения в публичном API (то есть те, которые не являются обратно совместимыми) должны оправдать основной выпуск. Таким образом, библиотека будет перепрыгивать с 1.7.3 до 2.0.0, что для меня слишком далеко. Мы говорим только об одной исправляемой функции.
У меня есть планы в конечном итоге выпустить 2.0.0, но я подумал, что это было, когда вы полностью переписали библиотеку и внесли многочисленные изменения в публичный API. Означает ли введение этого рефакторинга выпуск основной версии? Я действительно не могу видеть, как это происходит - я чувствую себя более комфортно, выпуская его как 1.8.0 или 1.7.4. У кого-нибудь есть совет?
next()
метод используется для извлечения текущего элемента и перемещения внутреннего указателя вперед. Что не так.next()
должен перемещать указатель иcurrent()
используется для извлечения ...next()
только того, что перемещает указатель, это действительно не нарушает совместимостьОтветы:
Вы сомневаетесь, потому что вы не хотите делать семантическое версионирование, вы хотите сделать «рекламу, поддерживающую версионирование». Вы ожидаете, что номер версии 2.0 сообщит миру, что у вас есть куча новых интересных функций в вашей библиотеке, а не то, что вы изменили API. Это нормально (многие компании-разработчики программного обеспечения и / или разработчики делают это). ИМХО у вас есть следующие варианты:
next
, просто добавьтеvalid
иcurrent
функцию). Тогда вы можете использовать «1.8.0» в качестве следующего номера версии. Если вы думаете, что изменение поведенияnext
действительно важно, сделайте это в 2.0.0.источник
next()
продолжать делать то, что он делает. Чтобы правильно реализовать функциональность, нужно сделать что-то по-другому. Так что, если я сделаю его обратно совместимым - новая функциональность / исправление также будет неправильной и подорвет весь смысл изменений.next()
метод, чтобы сделать все новые функциональные возможности, а также то, что было необходимо для обеспечения обратной совместимости. Это немного ужасно, чтобы запятнать новую функциональность, как это, но эй хо.Придерживайтесь руководства Тома по семантическому версионированию.
Любые существенные изменения в публичном API должны быть выполнены в любом из двух пунктов:
Мой голос, кстати, за первый. Но я признаю, что это подходит только для пустяков.
Проблема заключается в поддержании обратной совместимости и обеспечении того, чтобы вы не ломали вещи для предыдущих пользователей вашего API.
По сути, вы создаете ошибку индексации для своих пользователей, которые не знают об изменениях. Принудительное изменение, подобное этому, заставляет всех ваших пользователей делать следующее:
Это может потребовать больших усилий, особенно если учесть, как мало проектов имеют тестовые примеры для проверки изменений, подобных этой. Количество усилий увеличивается, если учесть количество последующих пользователей от ваших пользователей, которым также необходимо обновить свои установки.
Для чего-то такого маленького, я бы позволил этому уйти и не беспокоиться об этом.
Если это действительно беспокоит вас (что, по-видимому, так или иначе, вы бы не спросили), тогда я бы сделал следующее.
Release Notes
сообщить о предстоящем измененииА затем наберитесь терпения, так как потребуется время, чтобы накопить другие вещи, которые оправдывают обновление номера версии до нового основного выпуска. Расширенное уведомление (часть 3) дает вам время для получения отзывов от конечных пользователей, чтобы выяснить, какое влияние окажет это изменение.
Альтернативное решение - добавить новую функцию, которая работает так, как вы хотите.
Если у вас есть,
foo()
вы бы создалиfooCorrect()
, чтобы обеспечить исправление, но также полностью сохранить обратную совместимость. И в какой-то момент вы можетеfoo()
отказаться от того, чтобы другие знали, чтобы не использовать его.Проблема в том, что вы найдете что-то еще, в рамках
fooCorrect()
чего требуется его обновление, и вы в конечном итоге получитеfooCorrectedCorrect()
какую-то другую глупость.Если вы действительно хотите исправить это сейчас, этот альтернативный подход, вероятно, является наилучшим маршрутом. Будьте осторожны и создавайте множество дополнительных функций таким образом, так как это затрудняет работу с API. И этой осведомленности может быть достаточно, чтобы предотвратить худшие из этих типов проблем.
Но это может быть «наименее плохой» подход, чтобы рассмотреть что-то маленькое.
источник
next()
нетnextCorrect()
). Я посмотрю, смогу ли я изменить next (), чтобы он был обратно совместим и работал при реализацииIterator
интерфейса.