Parece uma experiência pouco frequente, mas comum, que às vezes você está trabalhando em um projeto e de repente algo aparece inesperadamente, lança uma chave de boca maciça nas obras e aumenta muito a complexidade.
Por exemplo, eu estava trabalhando em um aplicativo que falava com serviços SOAP em várias outras máquinas. Eu criei um protótipo que funcionou bem, depois desenvolvi um front end regular e, geralmente, colocava tudo em funcionamento de uma maneira agradável, bastante simples e fácil de seguir. Funcionou muito bem até que começamos a testar em uma rede mais ampla e, de repente, as páginas começaram a atingir o tempo limite, pois a latência das conexões e o tempo necessário para realizar cálculos em máquinas remotas resultaram em solicitações de tempo limite aos serviços de sabão. Aconteceu que precisávamos alterar a arquitetura para gerar solicitações em seus próprios encadeamentos e armazenar em cache os dados retornados, para que pudessem ser atualizados progressivamente em segundo plano, em vez de realizar cálculos em uma solicitação por solicitação.
Os detalhes desse cenário não são muito importantes - na verdade, não é um ótimo exemplo, pois era bastante previsível e as pessoas que escreveram muitos aplicativos desse tipo para esse tipo de ambiente podem tê-lo antecipado - exceto que ilustra uma maneira de pode-se começar com uma premissa e modelo simples e de repente ter uma escalada de complexidade até o desenvolvimento do projeto.
Quais estratégias você tem para lidar com esses tipos de mudanças funcionais cuja necessidade surge - geralmente como resultado de fatores ambientais e não de alterações nas especificações - posteriormente no processo de desenvolvimento ou como resultado de testes? Como você equilibra entre evitar os riscos prematuros de otimização / YAGNI / superengenharia de projetar uma solução que atenue problemas possíveis, mas não necessariamente prováveis , em vez de desenvolver uma solução mais simples e fácil, que provavelmente seja tão eficaz, mas não incorpore a preparação para toda eventualidade possível?
Editar: a resposta de Crazy Eddie inclui "você absorve e encontra a maneira mais barata de implementar a nova complexidade". Isso me fez pensar em algo implícito na pergunta, mas não levantei especificamente.
Depois de acertar o solavanco e incorporar as alterações necessárias. Você faz o que manterá o projeto o mais próximo possível do cronograma, mas pode afetar a capacidade de manutenção ou você volta à sua arquitetura e a refaz em um nível mais detalhado, que pode ser mais sustentável, mas atrasa tudo durante o desenvolvimento?
fonte
Não concordo com o espírito da resposta de @ Péter Török, porque pressupõe que uma equipe (ou indivíduo) possa necessariamente prever os itens mais arriscados no início do ciclo de vida do projeto. Por exemplo, no caso do OP, a equipe não podia prever a complexidade crescente associada à solução multithread até que suas costas estivessem contra a parede.A pergunta do OP é boa e mostra um problema que muitas lojas de desenvolvimento de software têm.
Aqui está como eu lidaria com o problema:
Mais sobre o ponto 3:
fonte
Código para interfaces
Ao escrever uma nova funcionalidade em interface com outra funcionalidade, faça um limite na forma de uma interface (o tipo Java) pela qual todas passam. Isso vai
fonte
Não é surpreendente.
Isso é desenvolvimento de software. Se você não está inventando algo novo, está baixando uma solução já comprovada.
Há pouco meio termo.
Se você está inventando algo novo, deve haver pelo menos um recurso que você não entende completamente. (Para entendê-lo completamente , você precisaria ter uma implementação funcional, que você usaria apenas.)
Como gerenciar isso?
Tenha expectativas realistas. Você está inventando algo novo. Não devem ser partes que você não entende.
Tenha expectativas realistas. Se parece funcionar bem na primeira vez, você ignorou alguma coisa.
Tenha expectativas realistas. Se fosse simples, alguém teria feito isso primeiro e você poderia simplesmente fazer o download dessa solução.
Tenha expectativas realistas. Você não pode prever o futuro muito bem.
fonte
Design e código com obsolescência em mente. Suponha que o que você codifique hoje precisará ser cortado e substituído amanhã.
fonte
O ambiente deve fazer parte da especificação. Assim, uma mudança no ambiente é uma mudança na especificação. Se, por outro lado, você baseou seu protótipo e design em um ambiente diferente do que estava na especificação, cometeu um erro tolo. De qualquer forma, você absorve e encontra a maneira mais barata de implementar a nova complexidade.
fonte
Como na maioria dos problemas de programação, isso depende , na minha opinião. Essa questão é tão intrínseca ao trabalho criativo, que você não deve esquecer que as falhas vão acontecer, e tudo bem . A programação é um problema grave e você normalmente não sabe a solução certa para o problema até que você já o tenha resolvido.
No entanto, existem vários fatores locais específicos que podem entrar em jogo aqui, como:
Para coisas de curto prazo, pode não valer a pena pensar nisso mais do que o suficiente para fazê-lo funcionar. A refatoração é cara e é algo que não cria valor final imediato para o usuário. Contudo, não há praticamente nenhum caso em que não seja um software descartável absoluto, em que é tão curto que não vale a pena melhorar seu design. É muito mais importante entender o que você fez e corrigi-lo rapidamente do que terminar agora. Se for a longo prazo, provavelmente será recompensado eventualmente (e possivelmente muito mais cedo do que todos os envolvidos pensam), ou o inverso (não fazê-lo causará dor muito em breve, em vez de "quando tivermos que consertá-lo"). Estou quase tentado a dizer "sempre reserve um tempo para melhorar", mas há alguns casos em que isso não é possível.
Isso deve influenciar enormemente suas decisões. Sua equipe apoiará essa decisão fornecendo recursos para a reformulação ou exigirá a solução rápida a ser feita agora. Na minha opinião, se você achar que a equipe está empurrando você na direção errada de forma consistente, é uma enorme bandeira vermelha. Eu já vi esse tipo de coisa acabar em um cenário em que há constante extinção de incêndio, onde nunca há tempo para redesenhar, porque você está sempre corrigindo os problemas que seu mau design cria. No entanto, também pode haver um meio termo: "fita adesiva" agora, corrija o mais rápido possível (mas realmente faça isso).
Muito importante. Pense sobre qual é o erro ou problema e por que está acontecendo. Esse tipo de situação é uma grande oportunidade para encontrar suposições, restrições e interações falhas (ou ausentes). Em geral, sempre favoreça entender melhor o seu problema em vez de resolvê-lo. Esta é provavelmente a sua maior defesa contra a YAGNI / superengenharia. Se você entender o seu problema bem o suficiente, então você vai resolver isso e não outros problemas.
Finalmente, tente construir as coisas da maneira certa . Não estou falando dos erros e problemas que você enfrenta quando entende mais sobre o problema ou sobre o erro humano inerente. Não quero dizer "não cometa erros e aperfeiçoe-o da primeira vez" - isso é impossível. Quero dizer, tente gerenciar bem a complexidade no seu trabalho diário, conserte janelas quebradas, mantenha o mais simples possível, melhore seu código e seu pensamento o tempo todo. Dessa forma, quando (e não se) mudar à sua porta, você poderá recebê-lo de braços abertos em vez de uma espingarda.
fonte