Atualmente, gerencio uma biblioteca que tem muito uso público e tive uma pergunta sobre o controle de versão semântico . Quero refatorar uma parte bastante importante da biblioteca que é implementada incorretamente - e sempre foi implementada incorretamente. Mas fazer isso significaria alterações na API pública, que é uma decisão importante.
A mudança que eu quero fazer gira em torno de como os iteradores são usados. Atualmente, os usuários precisam fazer isso:
while ($element = $iterator->next()) {
// ...
}
O que está incorreto, pelo menos na interface Iterator nativa do PHP . Eu quero substituir por isso:
while ($iterator->valid()) {
$element = $iterator->current();
// ...
$iterator->next();
}
que é análogo a:
foreach ($iterator as $element) {
// ...
}
Se você olhar o guia de Tom para versões semânticas, ele afirma claramente que qualquer alteração na API pública (ou seja, aquelas que não são compatíveis com versões anteriores) deve justificar uma versão importante. Portanto, a biblioteca saltaria de 1.7.3 para 2.0.0, o que, para mim, é um passo longe demais. Estamos falando apenas de um recurso que está sendo corrigido.
Tenho planos de finalmente lançar a 2.0.0, mas pensei que era quando você reescrevia completamente a biblioteca e implementava inúmeras alterações de API pública. A introdução dessa refatoração justifica o lançamento de uma versão principal? Realmente não consigo ver como funciona - me sinto mais confortável em liberá-lo como 1.8.0 ou 1.7.4. Alguém tem algum conselho?
next()
método é usado para recuperar o elemento atual E mover o ponteiro interno para frente. O que está errado.next()
deve mover o ponteiro, ecurrent()
é usado para recuperar ...next()
só isso é move o ponteiro, isso realmente não quebrar a compatibilidadeRespostas:
Você hesita porque não deseja criar versões semânticas, deseja criar "anúncios que suportam versões". Você espera que o número da versão "2.0" diga ao mundo que você tem um monte de novos recursos interessantes em sua biblioteca agora, não que tenha alterado a API. Tudo bem (muitas empresas de software e / ou desenvolvedores fazem isso). IMHO você tem as seguintes opções:
next
, basta adicionar as funçõesvalid
ecurrent
). Então você pode usar "1.8.0" como o próximo número da versão. Se você acha que mudar o comportamento denext
é realmente importante, faça-o na 2.0.0.fonte
next()
para continuar fazendo o que está fazendo. Para implementar a funcionalidade corretamente, é preciso fazer algo diferente. Portanto, se eu torná-lo compatível com versões anteriores - a nova funcionalidade / correção também estará errada e prejudicará todo o ponto da alteração.next()
método para fazer todas as novas funcionalidades, além do necessário para tornar a compatibilidade com versões anteriores. Parece horrível ter que manchar novas funcionalidades como essa, mas ei.Fique com o guia de Tom para versões semânticas.
Qualquer alteração significativa em uma API pública deve ser feita em um dos dois pontos:
Meu voto, a propósito, é o primeiro. Mas reconheço que isso é apropriado apenas para coisas triviais.
O problema é manter a compatibilidade com versões anteriores e garantir que você não quebre as coisas para os usuários anteriores da sua API.
Em essência, você está criando um erro de indexação para seus usuários que desconhecem a alteração. Forçar uma alteração como essa força todos os usuários a fazer o seguinte:
Isso pode ser um grande esforço, especialmente quando você considera o quão poucos projetos possuem casos de teste para validar alterações como essa. A quantidade de esforço aumenta quando você considera o número de usuários downstream de seus usuários que também precisarão atualizar suas instalações.
Para algo tão pequeno, eu deixaria passar e não me incomodaria.
Se isso realmente incomoda você (o que aparentemente incomoda ou você não teria perguntado), eu faria o seguinte.
Release Notes
antecipando a transmissão de que a mudança está chegandoE então seja paciente, pois levará um tempo para acumular outras coisas que justifiquem a atualização do número da versão para uma nova versão principal. A notificação avançada (parte 3) permite que você receba feedback dos usuários finais para descobrir quanto impacto essa mudança terá.
Uma solução alternativa é adicionar uma nova função que funcione da maneira que você deseja.
Se você tiver
foo()
, você criariafooCorrect()
para fornecer a correção, mas também preservar totalmente a compatibilidade com versões anteriores. E em algum momento você pode se preterirfoo()
para que outras pessoas saibam que não deve usá-lo.O desafio é que você encontrará outra coisa na
fooCorrect()
qual precisa ser atualizada e você teráfooCorrectedCorrect()
outras bobagens bobas.Se você realmente quer isso seja corrigido agora, essa abordagem alternativa é provavelmente a melhor rota. Esteja ciente e cauteloso de criar muitas funções extras dessa maneira, pois torna a API mais difícil de trabalhar. E essa conscientização pode ser suficiente para evitar o pior desses tipos de problemas.
Mas essa pode ser a abordagem "menos ruim" a considerar para algo pequeno.
fonte
next()
nãonextCorrect()
). Vou ver se consigo modificar next () para que seja compatível com versões anteriores E funcione ao implementar aIterator
interface.