- Há muitas incertezas em software.
- Por que ele é incerto?
- O maior motivo é a existência da complexidade do negócio
- Por causa da complexidade, a situação muda continuamente e, por isso, as previsões dos desenvolvedores têm grande chance de estar erradas.
- Uma torre construída com esforço desmorona e se transforma diretamente em dívida técnica.
- Um motivo menor é a falta de conhecimento e experiência
- Sem conhecimento e experiência, o próprio desenvolvedor pode criar dívida técnica por conta própria
- A complexidade do negócio é um fator externo que o desenvolvedor não pode controlar, enquanto conhecimento e experiência são fatores internos que o desenvolvedor pode controlar
- Há três caminhos para o desenvolvedor
- O caminho pessimista, que considera sem sentido lutar contra a complexidade
- Acaba dizendo coisas como “de qualquer forma vai mudar, então vamos só fazer”, “tecnologia não significa nada”
- Como é um caminho confortável e cômodo, a pessoa pode escolhê-lo sem perceber
- O caminho de ignorar a complexidade e pensar apenas em um ideal abstrato
- Acredita que é possível resolver tudo com uma única tecnologia que considera ideal
- Passa a ter um pensamento rígido e padronizado
- É um caminho em que desenvolvedores podem cair facilmente, mas do qual é difícil sair
- O caminho de aceitar a complexidade e enfrentá-la
- Mesmo aceitando que não se pode ser perfeito, continua tentando encontrar um caminho melhor
- É um caminho difícil, que exige resistência
- O desenvolvimento de software sempre lutou contra a complexidade
- Arquitetura, metodologias, Agile etc.
- O que aparecerá em seguida?
- Desenvolvimento orientado à destruição
- Quando olhamos para a realidade, é fácil cair no pensamento pessimista de que, de qualquer forma, tudo será apagado.
- Isso acontece porque é muito doloroso perceber que o código que escrevemos com tanto esforço fracassou e apagá-lo com as próprias mãos
- Em vez disso, que tal pensar ao contrário e fazer com que seja fácil apagar bem?
- A destruição é uma coisa boa?
- Sem destruição, nada novo pode nascer
- Em software, há dois grandes tipos de destruição: pivot e refatoração
- O pivot permite que a organização e o produto escolham um caminho melhor
- A refatoração é indispensável para prolongar a vida do software
- Então, o que é desenvolvimento orientado à destruição?
- É uma metodologia de desenvolvimento que aceita o fato de que, um dia, o código será destruído, e desenvolve já com isso em mente
- Busca três grandes princípios
- Se houver incerteza, reduza-a o máximo possível.
- Se for possível escolher entre vários métodos, escolha o lado mais fácil de destruir.
- Mantenha apenas o que é necessário. Portanto, apague tudo o que não for necessário.
- Análise -> separação de fronteiras -> implementação do código -> remoção da complexidade
- O ponto central é reduzir a incerteza causada por fatores internos e se preparar para a destruição causada por fatores externos inevitáveis
- Separação de fronteiras
- A incerteza é a taxa de mudança, e é possível separar com base nisso
- O desenvolvedor deve se preparar para fatores externos e reduzir ao máximo a taxa de mudança causada por fatores internos
- Como a taxa de mudança de cada fator pode variar entre organizações, é impossível expressá-la com números fixos -> mede-se de forma heurística
- ex) medição de story points
- É preciso decidir o nível de abstração com base no qual a separação será feita
- Possibilidade de destruição
- Na implementação, escolha o lado mais fácil de destruir de acordo com os princípios
- É possível avaliar a possibilidade de destruição considerando independência, compreensibilidade e controlabilidade
- A independência é julgada pelo grau de acoplamento e coesão e por quanto o princípio da responsabilidade única foi seguido
- A compreensibilidade é o quanto o desenvolvedor consegue olhar para o código e entendê-lo
- A controlabilidade é julgar se se trata de uma área que o desenvolvedor pode controlar
- Remoção da complexidade
- É preciso verificar se há coisas desnecessárias e removê-las. Ou seja, no final, a base de código deve conter apenas o que é necessário
- Se for difícil trabalhar nisso por questões como prazos, não há problema em apenas registrar e trabalhar depois
- Porque fatores internos são controláveis
- O essencial é manter a simplicidade ao máximo para se preparar para a destruição
- As técnicas de destruição de código
- Há vários princípios e métodos para apagar código com qualidade
- Dividir em etapas (padrão de refatoração)
- Preservar a transparência referencial
- Seguir o princípio da responsabilidade única
- Seguir o princípio da segregação de interfaces
- Padrão Strangler Fig
- Especialização de métodos
- Escrever código duplicado
- Registrar a taxa de mudança
6 comentários
Não concordo muito com a ideia de que dívida de código é criada por falta de conhecimento e experiência.
-> Pode ser que o tempo dado para implementar os requisitos não seja suficiente e, em casos de trabalho colaborativo, às vezes também é preciso tolerar um certo nível de dívida técnica para manter a harmonia com outras pessoas. Acho que as situações são variadas.
Também não entendo muito bem a ideia de ver conhecimento e experiência como fatores internos que o desenvolvedor pode controlar.
-> Os negócios são complexos, então não dá para prever que tipo de situação vai surgir, nem estudar todas as possibilidades a cada momento. E mesmo que você estude quando se depara com aquela situação, da próxima vez pode surgir um problema totalmente novo e aquele conhecimento acabar não servindo mais.
Olá. Obrigado por compartilhar sua opinião.
Acredito que só conseguimos ver a essência quando olhamos para o extremo. Nesse sentido, pensei que, se tivéssemos um conhecimento completo de
conhecimento e experiência, seria possível produzir código dentro do prazo sem gerar dívida.A falta de tempo pode ser dividida em dois casos. O primeiro é quando literalmente não há tempo suficiente para a implementação. Nesse caso, independentemente de conhecimento e experiência, falta o tempo físico para escrever o código. Portanto, as condições já tornam impossível atingir o objetivo desde o início. O segundo é quando não há tempo suficiente para descobrir o que é melhor. Nesses casos, como falta tempo para descobrir como implementar ou para encontrar algo melhor, o trabalho é concluído escrevendo código apenas com o conhecimento que se tem naquele momento. Quando o trabalho é concluído assim, você sabe que
há algo errado em algum lugar, mas não sabe exatamente como corrigir. Se houvesse conhecimento preciso e confiança adquirida por meio da experiência, esse problema não surgiria.Acredito que essa falta de tempo que mencionei acima sustenta minha opinião. Claro, na prática, é um problema extremamente difícil. Eu apenas falei de um ideal. É raro estar em um estado de conhecimento e experiência perfeitos e, como você mencionou, certamente há casos em que isso é suportado de propósito em nome da organização. Pode haver um sentimento de injustiça, mas pensei que,
levando isso ao extremo, esse problema surgiu por falta de conhecimento e experiência.Em segundo lugar, o fator interno que você mencionou é simples.
Os negócios são complexos, então não é possível prever que tipo de situação vai surgir...Essa parte, no texto que escrevi, é a discussão sobre acomplexidade do negócio. Ou seja, é um problema causado por fatores externos. Como são fatores externos, o desenvolvedor não pode controlá-los e acaba sentindo medo. Também aqui, se olharmos de forma extrema e assumirmos que não existe complexidade de negócio, restará apenas o código escrito pelo desenvolvedor. Nesse caso, sobrará apenas a questão deconhecimento e experiência, que pode ser controlada internamente.Claro, o texto que escrevi também é apenas a minha opinião. Podem existir contraexemplos suficientes. Acredito que a troca de opiniões é uma oportunidade de seguir por um caminho melhor. Espero continuar recebendo muitas opiniões no futuro. Obrigado.
Obrigado pela resposta gentil.
Gostei muito do texto. Parece que, dependendo do estágio da organização, o que é otimização prematura e o que é overengineering também muda. O ponto difícil é que é um código que de qualquer forma talvez precise ser reescrito, mas ao mesmo tempo nem sabemos se esse momento de reescrever vai realmente chegar. Às vezes eu também julgo com a pergunta: quando dizem que um serviço xxx ou uma funcionalidade vai deixar de existir, onde é mais adequado que o código yyy e os dados fiquem? Fico curioso para saber como outras pessoas fazem isso.
Também costumo pensar se, além do código, os dados ou o schema também podem desaparecer ou mudar.
Eu também queria incluir algo sobre dados, mas estava difícil organizar bem as ideias. Como é uma parte crítica, não é fácil mexer nisso de qualquer jeito, e também fiquei receoso porque isso pode acabar levando a um inferno de migração.
Como você mencionou, parece que a etapa inicial de design é muito importante, e o ponto-chave deve ser fazer com que os dados RAW sejam acumulados da melhor forma possível. Ou então uma arquitetura de event sourcing pode ser vantajosa do ponto de vista da exclusão. Claro, nunca usei essa arquitetura de fato, então não sei dizer se isso realmente seria válido.