Como lidar com o medo de assumir dependências

54

A equipe da minha equipe cria componentes que podem ser usados ​​pelos parceiros da empresa para integrar-se à nossa plataforma.

Como tal, concordo que devemos tomar muito cuidado ao introduzir dependências (de terceiros). Atualmente, não temos dependências de terceiros e precisamos permanecer no nível mais baixo da API da estrutura.

Alguns exemplos:

  • Somos forçados a permanecer no nível mais baixo da API da estrutura (.NET Standard). O raciocínio por trás disso é que uma nova plataforma poderá chegar um dia que suporta apenas esse nível de API muito baixo.
  • Implementamos nossos próprios componentes para (des) serializar o JSON e estamos fazendo o mesmo para o JWT. Está disponível em um nível superior da API da estrutura.
  • Implementamos um wrapper em torno da estrutura HTTP da biblioteca padrão, porque não queremos depender da implementação HTTP da biblioteca padrão.
  • Todo o código para mapear para / do XML é gravado "manualmente", novamente pelo mesmo motivo.

Sinto que estamos levando isso longe demais. Eu estou querendo saber como lidar com isso, já que isso afeta muito nossa velocidade.

Bertus
fonte
20
Existe uma justificativa para isso (por exemplo, requisito externo) ou está sendo feito por ignorância?
Blrfl
6
Faça um experimento com uma pequena parte da base de código, crie uma camada de isolamento que não tente ser uma biblioteca genérica, mas defina uma interface abstrata que modela suas necessidades; coloque sua própria implementação e uma dependência de terceiros por trás e compare como as duas versões funcionam / executam. Avalie os prós e os contras, avalie quão fácil (ou difícil) seria trocar trocas de implementações e tomar uma decisão. Em resumo, teste as coisas de maneira relativamente de baixo risco, veja o que acontece e decida.
Filip Milovanović
73
"Atualmente não temos dependências de terceiros" Isso sempre me faz rir quando as pessoas afirmam isso. Claro que você faz. Você não escreveu seu próprio compilador, IDE, implementação de nenhuma biblioteca padrão. Você não escreveu nenhuma das bibliotecas de objetos do shard que usa indiretamente (ou diretamente). Quando você percebe a quantidade de software e bibliotecas de terceiros de que depende, você pode abandonar a idéia "dependências são ruins" e simplesmente não gosta de reinventar a roda. Gostaria apenas de sinalizar as dependências que você tem e depois perguntar por que elas são aceitáveis, mas o json parsing não é.
UKMonkey
8
Dito isto, há desvantagens alternativas, como nunca terminar projetos. Mas promove trabalhos de software e emprego :)
marshal craft
5
Você está certo de que está desperdiçando esforço reinventando o software de commodities. Você está errado, pois isso não chega nem perto de "evitar todas as dependências". Uma vez, a equipe do Excel na Microsoft escreveu seu próprio compilador C para evitar depender da equipe C da Microsoft . Você está assumindo enormes dependências de sistemas operacionais, estruturas de alto nível e assim por diante.
Eric Lippert

Respostas:

94

... Somos forçados a permanecer no nível mais baixo da API da estrutura (.NET Standard)…

Isso para mim destaca o fato de que, não apenas você está se restringindo demais, como também pode estar caminhando para uma queda desagradável com sua abordagem.

O .NET Standard não é e nunca será " o nível mais baixo da API da estrutura ". O conjunto mais restritivo de APIs para .NET é obtido através da criação de uma biblioteca de classes portátil que se destina ao Windows Phone e Silverlight.

Dependendo da versão do .NET Standard que você está direcionando, você pode acabar com um conjunto muito rico de APIs compatíveis com o .NET Framework, .NET Core , Mono e Xamarin . E há muitas bibliotecas de terceiros compatíveis com o .NET Standard que, portanto, funcionarão em todas essas plataformas.

Depois, existe o .NET Standard 2.1, que provavelmente será lançado no outono de 2019. Ele será suportado pelo .NET Core, Mono e Xamarin. Não será suportado por nenhuma versão do .NET Framework , pelo menos no futuro próximo e, provavelmente, sempre. Portanto, em um futuro próximo, longe de ser " o nível de API mais baixo da estrutura ", o .NET Standard substituirá a estrutura e terá APIs que não são suportadas por este último.

Portanto, tenha muito cuidado com " O raciocínio por trás disso é que uma nova plataforma poderá chegar um dia que suporte apenas esse nível de API muito baixo ", pois é bem provável que novas plataformas de fato suportem uma API de nível superior à estrutura antiga.

Depois, há o problema de bibliotecas de terceiros. JSON.NET, por exemplo, é compatível com o .NET Standard. Qualquer biblioteca compatível com o .NET Standard é garantida - em termos de API - para funcionar com todas as implementações do .NET compatíveis com essa versão do .NET Standard. Portanto, você não obtém compatibilidade adicional ao não usá-lo e criar sua biblioteca JSON. Você simplesmente cria mais trabalho para si e incorre em custos desnecessários para sua empresa.

Então, sim, você definitivamente está levando isso muito longe, na minha opinião.

David Arno
fonte
16
"Você simplesmente cria mais trabalho para si e incorre em custos desnecessários para sua empresa". - e passivos de segurança. Seu codificador JSON trava com um estouro de pilha se você der um objeto recursivo? Seu analisador lida com caracteres de escape corretamente? Rejeita caracteres não escapados que deveria? Que tal personagens substitutos não emparelhados? Estouro quando o JSON codifica um número maior que 2 ^ 64? Ou é apenas um pequeno evalinvólucro com algumas verificações de sanidade que são facilmente ignoradas?
John Dvorak
4
"O conjunto mais restritivo de APIs para .NET é alcançado através da criação de uma biblioteca de classes portátil voltada para Windows Phone e Silverlight." Vou falar sobre o assunto e afirmar que há pelo menos algumas APIs nesse subconjunto que não são suportadas por todas as implementações possíveis que já existiram (e ninguém mais se importa com o WinPhone ou o Silvernight, nem mesmo a microsoft). Usar o .NetStandard 2.0 como alvo de uma estrutura moderna parece muito prudente e não particularmente limitativo. A atualização para 2.1 é uma história diferente, mas não há indicação de que eles o fariam.
Voo
Além das plataformas futuras, provavelmente suportando mais do que menos, o desenvolvimento de todas as coisas que podem acontecer é incrivelmente caro (e é provável que você perca alguma coisa). Em vez disso, desenvolver sem reinventar a roda vai economizar mais tempo do que se adaptar a uma nova situação, quando o que é necessário vai custo.
Jasper
51

Somos forçados a permanecer no nível mais baixo da API da estrutura (padrão .net). O raciocínio por trás disso é que uma nova plataforma poderá chegar um dia que suporta apenas esse nível de API muito baixo.

O raciocínio aqui é bastante inverso. Níveis de API mais antigos e mais baixos têm mais probabilidade de se tornar obsoletos e sem suporte do que os mais novos. Embora eu concorde que é sensato manter-se confortável atrás da "vanguarda" para garantir um nível razoável de compatibilidade no cenário mencionado, nunca avançar é além do extremo.

Implementamos nossos próprios componentes para (des) serializar JSON e estamos fazendo o mesmo para o JWT. Está disponível em um nível superior da API da estrutura. Implementamos um wrapper em torno da estrutura HTTP da biblioteca padrão porque não queremos depender da impulsão HTTP da biblioteca padrão. Todo o código para mapear para / do XML é gravado "manualmente", novamente pelo mesmo motivo.

Isso é loucura . Mesmo que você não queira usar as funções de biblioteca padrão por qualquer motivo, as bibliotecas de código aberto existem com licenças compatíveis comercialmente que fazem tudo isso acima. Eles já foram escritos, extensivamente testados do ponto de vista da funcionalidade, segurança e design da API e usados ​​extensivamente em muitos outros projetos.

Se o pior acontecer e esse projeto desaparecer ou parar de ser mantido, você terá o código para construir a biblioteca de qualquer maneira e designará alguém para mantê-lo. E você provavelmente ainda está em uma posição muito melhor do que se tivesse criado o seu próprio, pois, na realidade, você terá mais código testado, mais limpo e mais sustentável para cuidar.

No cenário muito mais provável de manutenção do projeto, e bugs ou explorações forem encontrados nessas bibliotecas, você saberá sobre eles para fazer algo a respeito - como atualizar para uma versão mais nova gratuitamente ou corrigir sua versão com a correção, se você tirou uma cópia.

berry120
fonte
3
E mesmo se você não puder, mudar para outra biblioteca ainda é mais fácil e melhor do que criar sua própria.
Lightness Races com Monica em
5
Excelente ponto que coisas de nível inferior morrem mais rápido. Esse é o objetivo de estabelecer abstrações.
Lightness Races com Monica em
"Níveis de API mais antigos e mais baixos têm maior probabilidade de se tornar obsoletos e sem suporte do que os mais novos". Hã? Os NetSTandards são construídos um sobre o outro, tanto quanto eu sei (o que significa 2.0 é 1.3 + X). Além disso, os padrões são simplesmente esses ... padrões, não implementações. Não faz sentido falar que um padrão não é suportado; as implementações mais específicas desse padrão podem ser no futuro (mas veja o ponto anterior por que isso também não é uma preocupação). Se a sua biblioteca não precisa de nada fora do NetStandard 1.3, não há absolutamente nenhuma razão para alterá-la para 2.0
Voo
11

No geral, essas coisas são boas para seus clientes. Mesmo uma biblioteca popular de código aberto pode ser impossível para eles usarem por algum motivo.

Por exemplo, eles podem ter assinado um contrato com seus clientes prometendo não usar produtos de código aberto.

No entanto, como você ressalta, esses recursos não são isentos de custos.

  • Tempo para o mercado
  • Tamanho do pacote
  • atuação

Eu elevaria essas desvantagens e conversaria com os clientes para descobrir se eles realmente precisam dos níveis uber de compatibilidade que você está oferecendo.

Se todos os clientes já usam o Json.NET, por exemplo, usá-lo em seu produto, em vez de seu próprio código de desserialização, reduz seu tamanho e o aprimora.

Se você introduzir uma segunda versão do seu produto, uma que use bibliotecas de terceiros e uma compatível, poderá julgar a aceitação de ambas. Os clientes usarão os terceiros para obter os recursos mais recentes um pouco mais cedo ou seguirão a versão 'compatível'?

Ewan
fonte
11
Sim, eu obviamente concordo e acrescentaria "segurança" à sua lista. Há algum potencial de que você possa introduzir uma vulnerabilidade no seu código, especialmente com coisas como JSON / JWT, em comparação com estruturas bem testadas e definitivamente a biblioteca padrão.
Bertus 08/04
Sim, é difícil fazer a lista porque, obviamente, coisas como segurança e desempenho podem ter os dois lados. Mas há um óbvio conflito de interesses entre os recursos de acabamento e a garantia de que os componentes internos são totalmente compreendidos / compreendidos
Ewan
12
"eles podem ter assinado um contrato com seus clientes prometendo não usar produtos de código aberto" - eles estão usando o .NET Standard, que é de código aberto. É uma má idéia assinar esse contrato quando você baseia todo o seu produto em uma estrutura de código aberto.
Stephen
E ainda as pessoas fazem isso
Ewan
7

Resposta curta é que você deve começar a introduzir dependências de terceiros. Durante sua próxima reunião, diga a todos que na próxima semana de trabalho será a mais divertida que eles tiveram em anos - eles substituirão os componentes JSON e XML por soluções de bibliotecas padrão de código aberto. Diga a todos que eles têm três dias para substituir o componente JSON. Comemore depois que terminar. Ter uma festa. Vale a pena comemorar.

Visão dupla Stout Fat Heavy
fonte
2
Pode ser uma língua na bochecha, mas não é irreal. Entrei para uma empresa em que um desenvolvedor "sênior" (sênior apenas por educação) havia encarregado um desenvolvedor júnior de escrever uma biblioteca de máquinas de estado. Ele tinha cinco meses de desenvolvedor e ainda estava com defeito, então eu o retirei e substituí por uma solução pronta para uso em questão de alguns dias.
No U
0

Basicamente, tudo se resume a esforço versus risco.

Ao adicionar uma dependência adicional ou atualizar sua estrutura ou usar uma API de nível superior, você reduz seu esforço, mas assume riscos. Então, eu sugeriria fazer uma análise SWOT .

  • Pontos fortes: Menos esforço, porque você não precisa codificá-lo.
  • Fraquezas: não é tão personalizado para suas necessidades especiais quanto uma solução artesanal.
  • Oportunidades: o tempo de colocação no mercado é menor. Você pode lucrar com desenvolvimentos externos.
  • Ameaças: você pode incomodar os clientes com dependências adicionais.

Como você pode ver, o esforço adicional para desenvolver uma solução artesanal é um investimento na redução de suas ameaças. Agora você pode tomar uma decisão estratégica.

Dominic Hofer
fonte
-2

Divida suas bibliotecas de componentes em um conjunto "Principal", que não possui dependências (essencialmente o que você está fazendo agora) e um conjunto "Comum", que possui dependências em suas bibliotecas "Principal" e de terceiros.

Dessa forma, se alguém quiser apenas a funcionalidade "Principal", poderá obtê-la.

Se alguém quiser a funcionalidade "Comum", poderá obtê-la.

E você pode gerenciar o que é "Core" versus "Common". Você pode adicionar funcionalidades mais rapidamente a "Comum" e movê-las para sua própria implementação "Principal" se / quando fizer sentido fornecer sua própria implementação.

Tartaruga1363
fonte