Em qualquer cenário, quanto maior a complexidade, maiores são os custos envolvidos. Por isso, tanto na elaboração quanto na avaliação de designs arquiteturais, onde geralmente se busca otimizar o custo – que é um atributo de qualidade – é natural a busca pelo “mais simples”. Infelizmente, a complexidade emerge com a necessidade de entregar mais valor para o negócio e suportar melhor a escala, preservando a confiabilidade.
A complexidade tem quatro origens genéricas distintas que devem ser combatidas ou, pelo menos, controladas. São elas: dimensionalidade, interdependência, influência do ambiente e irreversibilidade. \
Dimensionalidade
Quanto maior o número de variáveis envolvidas, maior será a dimensionalidade. Por isso, por exemplo, qualquer software com mais features se torna mais complexo. A cada novo processo na organização, menor a simplicidade. Toda exceção suportada aumenta o custo.
Em uma arquitetura monolítica, mais código significa mais complexidade para desenvolvedores. Em uma arquitetura baseada em microsserviços, mais artefatos para distribuir, independentemente, significa mais complexidade para a operação. É parte das práticas de arquitetura determinar onde dimensionalidade maior representa mais problemas. Entretanto, dimensionalidade é uma fonte impossível de evitar em definitivo.
Interdependência e relações
Na medida em que as expectativas relacionadas a software aumentam, crescem também as demandas por adotar soluções “prontas” que possibilitem atender as demandas do negócio.
Quanto mais componentes externos em um sistema, maiores os desafios para controlar a evolução das versões e balancear a atualização tecnológica com a necessidade de implementar features.
Influência do ambiente
Operações interdependentes demandam mais esforço de comunicação e sincronização. Não raro, a indisponibilidade de um recurso impossibilita o uso de outro, aparentemente não relacionado. É bastante comum que uma performance mais pobre de uma parte de um sistema deixe ele todo “lento”.
A influência do ambiente é “afrouxada” pela utilização de técnicas resilientes e adoção de abstrações. Entretanto, “nenhum sistema é uma ilha” e, em geral, a influência do ambiente pode ser minimizada, mas não evitada.
Irreversibilidade
Decisões irreversíveis implicam em mais planejamento, cuidado na implementação, testes e, consequentemente, complexidade.
A adoção de metodologias ágeis substituíram longos ciclos de desenvolvimento por abordagens iterativas, mais fáceis de verificar e validar. Da mesma forma, servidores imutáveis tornaram mais fáceis executar o deploy e, principalmente, rollbacks.
Toda decisão arquitetural que não pode ser desfeita implica em complexidade.