Digamos que você tenha uma interface IFoo
:
public interface IFoo {
void Bar(string s);
int Quux(object o);
}
Na versão 2 da sua API, você precisa adicionar um método Glarg
a essa interface. Como você faz isso sem quebrar os usuários existentes da API e manter a compatibilidade com versões anteriores? O objetivo é principalmente o .NET, mas também pode ser aplicado a outras estruturas e linguagens.
versioning
interfaces
thecoop
fonte
fonte
Respostas:
Por quê?
As interfaces definidas para uso com uma API têm duas funções totalmente diferentes:
Agora, para uma determinada versão de uma API, a mesma interface pode atuar como ambas. Ainda assim, em versões futuras, isso pode ser dissociado.
Você deseja "retornar mais", ou seja, a abstração de um objeto "mais rico" da sua API. Aqui você está tendo duas opções:
Defina uma nova interface, se possível derivada da anterior. Se essa derivação for impossível, crie métodos separados para consultar instâncias da nova interface ou use a composição:
fonte
O DirectX adicionou números de versão às suas interfaces. No seu caso, a solução seria algo como
A API ainda se referiria ao IFoo e ao IFoo2 apenas em métodos etc, onde a funcionalidade do IFoo2 é necessária.
A implementação da API deve verificar nos métodos existentes (= versão 1) se um objeto de parâmetro IFoo realmente implementa o IFoo2, se a semântica do método for diferente para o IFoo2.
fonte
A adição de um novo método (ou métodos) à sua API deve ser feita de forma a não causar efeitos colaterais na API existente. Mais importante, alguém que continua a usar a API antiga como se a nova API não existisse, não deve ser afetado por ela. O uso da API antiga também não deve ter efeitos colaterais inesperados na nova API.
Se algum dos métodos existentes na API for substituído pelos novos, não os remova imediatamente. Marque-os como obsoletos e forneça uma explicação sobre o que deve ser usado. Isso avisa os usuários do seu código que versões futuras podem não mais dar suporte a ele, em vez de quebrar o código sem aviso.
Se as APIs novas e antigas forem incompatíveis e não puderem viver juntas sem efeitos colaterais indesejados, separe-as e documente que, se a nova API for adotada, a API antiga deverá ser completamente retirada. Isso é menos desejável, pois sempre haverá alguém que tenta usar os dois e fica frustrado quando não funciona.
Como você perguntou sobre o .NET especificamente, convém ler este artigo sobre descontinuação no .NET, que possui links para o
ObsoleteAttribute
(usado no exemplo a seguir):fonte
Alterações na interface pública envolvem quebra. A estratégia comum é fazer isso apenas nas versões principais e após um período de congelamento (para que isso não ocorra por um capricho). Você pode fugir sem prejudicar seus clientes se estiver adicionando adições a uma nova interface (e sua implementação pode fornecer ambas na mesma classe). Isso não é o ideal, e se você continuar fazendo isso, terá uma bagunça.
Porém, com outros tipos de modificação (remoção de métodos, alteração de assinaturas), você fica preso.
fonte
Uma interface é um contrato, portanto, não deve ter controle de versão. O que acontece se um jogador de futebol conseguir um novo contrato? O antigo ainda é válido? Não. Se alguém alterar a interface, o contrato será alterado e o contrato anterior (interface) não será mais válido.
Embora você possa usar a estratégia IFoo2, eventualmente isso ficará confuso quando você tiver:
Que nojo.
Uma API é diferente. Dou biblioteca de código para usar. No próximo mês, eu lhe darei uma biblioteca atualizada. Como outro pôster disse, não quebre o que já estou usando, basta adicionar novas funcionalidades / métodos.
Se você quiser versão alguma coisa, use uma classe abtract em vez de uma interface.
fonte