Software relevante evolui... e a arquitetura precisa suportar isso!

Este capítulo possui uma versão mais recente:

Há muito tempo acreditamos que, quando a taxa de mudança dentro de uma instituição se torna mais lenta do que a taxa de mudança externa, o fim está à vista. A única questão é quando.
Jack Welch

Software relevante evolui! Seja para atender novas demandas do negócio, seja para incorporar novidades tecnológicas, adaptações são sempre necessárias. Enquanto isso, é fato que modificar software fica, geralmente, mais difícil com o tempo.

Apesar de nossos melhores esforços, o software se torna mais difícil de alterar com o tempo. Por uma variedade de razões, as partes que compõem os sistemas de software desafiam a modificação fácil, tornando-se mais frágeis e intratáveis com o tempo. Mudanças em projetos de software são geralmente conduzidas pela reavaliação da funcionalidade e/ou escopo.

Ford, Parsons e Kua

As mudanças, seja nos negócios ou na tecnologia, acontecem em um ritmo cada vez mais acelerado. O software precisa evoluir em um ritmo compatível com essas mudanças, caso contrário, se tornará irrelevante rápido, precisando ser substituído. Ainda pior, eventualmente, “trocar” de software não é uma opção – nesses casos, o prejuízo é mais grave e pode ser irreparável.
0
Você concorda?x

Negócios e tecnologias, eventualmente, podem evoluir em ritmos diferentes e por razões diferentes, e o software deve suportar ambos os tipos de mudança, mas, logo, não, necessariamente, na mesma velocidade. As mudanças de negócio impactam diretamente a razão da existência de qualquer aplicação. Dessa forma, quando se ela não não evolui, ela não atende mais o motivo pelo qual foi criada. Já as mudanças de tecnologia impactam na possibilidade de permitir o software continuar evoluindo para continuar atendendo o negócio.

Por tudo isso, Evolvability é um importante atributo de qualidade para qualquer boa arquitetura, senão o mais importante.
0
Você concorda?x

Fixing Problems

As leis de Lehman

Ao longo de décadas, Meir Lehman e László Bélády formularam, propuseram e aprimoraram diversas “leis” que, alegadamente, governam a evolução de sistemas de software. Essas leis ficaram conhecidas como “Leis de Lehman”.

As “Leis de Lehman” descrevem e ajudam a entender o sensível equilíbrio entre as motivações para a evolução de um software, por adaptações, e as causas para o aumento da complexidade (em consequência, do lead time para atender demandas do negócio) ao longo do tempo.

As duas primeiras “leis” formuladas por eles, em 1974, foram a lei da “mudança contínua” e a lei da “complexidade crescente”. A primeira diz que, ao longo do tempo, um sistema de software precisa ser continuamente adaptado, recebendo novas “adaptações”, para se manter relevante e satisfatório. A segunda aponta que, enquanto essas “adaptações” são feitas, o software se torna mais complexo, exceto quando existam esforços explicitamente direcionados para mitigar essa complexidade.

Qual é a relação existente entre a imagem e o texto da charge? - Brainly.com.br

As duas leis, deliciosamente evidentes e conflitantes, levam a alguns desdobramentos preocupantes:

  • Projetos de software bem sucedidos estão “condenados” a demandarem trabalho para mitigar a a complexidade.
  • Times extremamente eficazes, mas exclusivamente focados em atender as demandas de negócio se tornam, eventualmente, menos produtivos, deteriorando sua capacidade de fazer entregas e, consequentemente, sua eficácia.
    0
    Você concorda?x
  • O esforço para combater a complexidade é imperativo para manter o software relevante no médio/longo prazo.
  • Times de negócio que não se sensibilizam para a necessidade de reduzir a complexidade do software, priorizando somente inclusão de features, se condenam a ter suas demandas atendidas em prazos cada vez maiores.
    0
    Você concorda?x

Dívida técnica

Dívidas técnicas surgem quando desenvolvedores de software, de forma deliberada ou não, abrem mão de boas práticas de desenvolvimento para ganhar algum tempo. Entretanto, acabam sofrendo, mais tarde, com os custos e tempos de manutenção mais altos.

Mudanças tecnológicas acontecem rapidamente e têm impactos imprevisíveis

O conjunto de tecnologias, técnicas, padrões e boas práticas para desenvolver software são dinâmicas e instáveis. Essa instabilidade, aliás, é um dos principais desafios para manter e evoluir sistemas.
0
Você concorda?x

A emergência de práticas como a utilização de contêiners, aceleradas por tecnologias como Docker, por exemplo, impactam a indústria de forma definitiva e, para os menos “antenados”, parece surgir de uma hora para outra.

Linguagens novas de programação, mais expressivas (pelo menos para alguns domínios) também surgem em ritmo cada vez mais acelerado. Recentemente, mesmo as linguagens consolidadas também passaram a receber atualizações mais frequentes. Em consequência disso, bases de código gigantes que geram sistemas em produção, parecem cada vez mais “legadas” em prazos cada vez mais curtos.
0
Você concorda?x

Frameworks Javascript parecem crescer em popularidade e se tornarem obsoletas em ciclos, muitas vezes, menores do que os necessários para o desenvolvimentos de alguns grandes sistemas. Em poucos anos, vimos o declínio de jQuery; a ascensão e a “morte” de AngularJS; a “provocação” de Backbone e Mustache; o progresso com Angular, React e Vue; propostas ousadas multiplataforma como Flutter e Electron; etc. É quase impossível dizer qual será a tecnologia dominante para elaboração de frontends de aqui dois anos.

Não conseguimos predizer quando mudanças impactantes do contexto de desenvolvimento irão ocorrer. Nem mesmo conseguimos antecipar quais serão “persistentes” (se é que essa palavra é aplicável), entretanto, sabemos que mudanças acontecem e o ritmo parece ser cada vez mais acelerado.
0
Você concorda?x
Adicionar evolucionabilidade como uma característica arquitetônica implica proteger as outras características conforme o sistema evolui. Por exemplo, se um arquiteto projetou uma arquitetura para escalabilidade, ele não sabe o que essa característica degradar à medida que o sistema evolui. Assim, a evolucionabilidade é uma meta-característica, um invólucro arquitetônico que protege todas as outras características arquitetônicas.

Ford, Parsons e Kua

O que é arquitetura evolucionária

O conceito de arquitetura evolucionária foi consolidado no excelente livro Building Evolutionary Architectures, escrito por Neil Ford, Rebecca Parsons e Jason Kua. Lá, eles propõe que arquiteturas evolucionárias são aquelas que 1) suportam mudanças incrementais guiadas; 2) em várias dimensões. Partindo da definição proposta, é possível inferir que toda arquitetura evolucionária tem “evolvability” entre seus atributos de qualidade.

A escolha da palavra “evolucionária” é bastante interessante. Ela se afasta, de certa forma, do conceito de “emergência”e de arquitetura emergente. Ou seja, não tem como lema desenvolver a arquitetura de maneira “desregrada”, simplesmente respondendo ao contexto de maneira desordenada. Assim, arquitetura evolucionária é algo muito diferente de “não-arquitetura”, ou da “Arquitetura Zeca Pagodinho” (🎶 deixa a vida me levar, vida leva eu! 🎵).
0
Você concorda com essa afirmação? Há algo a ponderar aqui?x

A arquitetura evolucionária preconiza suportar as mudanças, de maneira incremental. De maneira ampla, assume-se que a filosofia evolucionária defende que, sempre que possível, mudanças devem ser aplicadas aos poucos, sem grandes saltos ou descontinuidades. Dessa forma, o “custo da mudança” fica diluído causando “menos dor”.

A evolução incremental, para ser segura, precisa ser guiada! Quanto menos “guiada”, maior o risco. Ao longo do tempo, na medida em que as mudanças ocorrem, é importante que os compromissos da arquitetura de software sejam relembrados e reafirmados. A cada mudança, é necessário identificar se houve aproximação ou afastamento dos objetivos do negócio, se as restrições continuam sendo observadas e se os atributos de qualidade estão sendo observados. Esse “cuidado” precisa ocorrer de forma objetiva e, sempre que possível, automatizada ou, pelo menos, incorporada a rotina. A proposta central passa por definir architectural fitness functions.

Finalmente, a arquitetura evolucionária lida com múltiplas dimensões, tentando preservar o equilíbrio. Melhorias na performance não podem comprometer a disponibilidade ou a segurança, por exemplo. A visão arquitetural é, dessa forma, holística.

A evolvability é, em última instância, a principal conexão entre a arquitetura de software e a escrita de código.

Postergando decisões para o “último momento responsável”

Toda decisão implica em assumir riscos. Quanto antes uma decisão é tomada, maiores são os riscos associados a possibilidade dessa decisão representar um erro causando prejuízos.

O início dos projetos de desenvolvimento de software, onde tradicionalmente residem boa parte das “ações arquiteturais”, é, curiosamente, também, o momento onde se sabe menos sobre objetivos de negócio, restrições e atributos de qualidade.
0
Você concorda?x

The General Problem


Quanto mais tarde, em um processo de desenvolvimento, uma decisão é tomada, maior é quantidade de informações disponíveis para fundamentar uma decisão e, consequentemente, maiores são as chances de acerto e, proporcionalmente, menor é o risco.
0
Você concorda?x

As atividades de um arquiteto, em um contexto evolucionário, são o da busca constante da resolução de incertezas. Aliás, o grande inimigo é a incerteza! Isso não significa, entretanto que o arquiteto não deva ter, a todo momento, a “escolha-com-os-dados-de-agora”. Ou seja, documentos arquiteturais e discussões precisam revelar a “posição atual” da arquitetura, indicando, porém, onde estão os pontos de maior incerteza.

No início dos projetos, a principal preocupação dos arquitetos é explicitar a estratégia – padrões coerentes para tomada de decisão – que deve ser observada nas escolhas. Se possível, essa “estratégia” precisa ser objetiva e observável, expressa em architectural fitness functions. Arquitetura evolucionária não é emergente, nem baseada em palpites.

A evolução demanda implementação incremental das mudanças

O “represamento” das iniciativas para modernização tecnológica é uma das maiores causas para a “morte” dos sistemas de software. Mesmo quando tecnologias não agregam “algo novo”, o afastamento da trajetória evolutiva das ferramentas, técnicas e práticas por um tempo prolongado aumenta de maneira exponencial o custo e risco para a mudança, apesar dos custos de oportunidade.
0
Você concorda?x

É fundamental tentar “conectar” a atualização tecnológica com um benefício tangível, seja para o atingimento dos objetivos do negócio, respeito as restrições ou atributos de qualidade, implicando, invariavelmente em ganho econômico objetivo e mensurável. A falta da noção clara dos ganhos de uma mudança, em pelo menos uma direção, é sintoma da falta de maturidade para implantar tal mudança. Aliás, raciocínio análogo deve ser aplicado a dívidas técnicas: elas importam apenas quando cobram juros.
0
Você concorda?x
Um sistema se torna legado quando nossa capacidade de pagar dívidas técnicas é menor que a necessidade de contrair novas.

Fernando Paiva

A boa arquitetura permite e facilita que atualizações incrementais sejam realizadas. Um software onde o front-end esteja “emaranhado” com a lógica do negócio é, naturalmente, difícil de atualizar tecnologicamente. Por outro lado, quando há “inteligência demais” no front-end, a atualização é mais difícil.

A utilização de REST, por exemplo, pode facilitar a atualização tecnológica quando, além dos dados relacionados aos recursos, as ações possíveis sejam indicadas formando uma verdadeira máquina de estados.
0
Você utiliza REST assim?x
HTTP/1.1 200 OK
Content-Type: application/vnd.acme.account+json
Content-Length: ...

{
  "account": {
      "account_number": 12345,
      "balance": {
        "currency": "usd",
        "value": 100.00
       },
      "links": {
          "deposit": "/accounts/12345/deposit",
          "withdraw": "/accounts/12345/withdraw",
          "transfer": "/accounts/12345/transfer",
          "close": "/accounts/12345/close"
      }
  }
}

Decisões de design assim, tiram do front-end a responsabilidade de decidir quando mostrar, ou não, um botão ou link. Um dos grandes inimigos da implantação de mudanças é o acoplamento e, por isso, ele deve ser evitado.

Finalmente, para que mudanças incrementais sejam implementadas da maneira certa, o conjunto mais leve de ferramentas e documentação (protip: documentação leve é diferente de não-documentação) deve ser implantado. Governança não é, nem pode ser, justificativa para “atrofiar a inovação”.
0
Por favor, deixe seu feedback aquix

A prática da arquitetura evolutiva demanda métricas de qualidade interna

Código limpo e fácil de entender demanda menos esforço cognitivo e, por consequência, é mais fácil de mudar. 

Indicadores simples como complexidade aferente e eferente, quando bem analisados autorizam identificar e priorizar pontos de atuação e desafios arquiteturais para a mudança.

Análise da complexidade ciclomática, embora não seja precisa, costuma funcionar como um bom proxy para identificar pontos do código que irão consumir mais tempo para a mudança.
Finalmente, a análise de frequência de mudanças nos repositórios ajuda a determinar que códigos são mais sujeitos a falha e onde mais documentação faz diferença.
0
Você concorda?x

No gráfico acima, podemos ver que há clara concentração de commits em uma parcela muito pequena de arquivos no projeto do servidor do RavenDB, por exemplo. Um arquivo, apenas, recebeu 3% de todos os commits. Mais de 50% dos commits envolveu menos de 10% de toda a base de código. Parece evidente que as dívidas técnicas presentes nesses arquivos acabariam tendo impactos muito mais altos para a produtividade do time. Também parece lógico que o código desses arquivos fosse aquele com maior cobertura por testes automatizados.

A implementação de métricas e o acompanhamento vigilante previne que desvios grandes de qualidade acontençam antes que algo possa ser feito para colocar as “coisas certas nos lugares certos”. Quando uma métrica “sai do controle”, é importante que a normalidade  seja restabelecida no tempo certo.

É importante entretanto não perder de vista da motivação do interesse da arquitetura pelo código: garantir o evolvability!
0
Você concorda?x

Arquiteturas evolutivas combatem as “origens” da complexidade

A complexidade tem quatro origens genéricas distintas que devem ser combatidas. São elas: dimensionalidade, interdependência, influência do ambiente e irreversibilidade.

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.

Operações interdependentes demandam, por exemplo, 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”.

Sistemas mais “sensíveis” ao ambiente também são mais complexos. Afinal, demandam planejamento de contingências e workarounds.

Finalmente, a irreversibilidade também demanda cuidados. Ações ou eventos cujo ocorrências resultem em consequências que não podem ser desfeitas implicam em custo maior de planejamento, nem sempre eficiente. Boa parte das estratégias modernas de desenvolvimento conta com o pressuposto de um “rollback” rápido. Este é o fundamento de iniciativas operacionais como DevOps.

Naturalmente, sistemas tendem para o incremento da dimensionalidade e da interdependência. Além disso, em ambientes cada vez mais abrangentes, é difícil controlar o impacto do ambiente, marcando, de forma irreversível impactos e prejuízos.  Se o empenho de um time for orientado a apenas manter os níveis atuais de complexidade, essa irá aumentar.

Sistemas que seguem a lei de Postel evoluem mais fácil

Lei de Postel — ou Lei da Robustez — é um princípio originalmente descrito como um guia para a transferência de dados entre softwares. Contudo, ela é bastante compatível com arquitetura.

A lei preconiza que sistemas sejam 1) conservadores no que enviam e ; 2) liberais no que recebem;

Standards

A evolução é segura quando “fitness functions” são determinadas

Architectural Fitness Functions” é um conceito inspirado nas fitness functions utilizadas com algoritmos genéticos.

Uma função de adequação (fitness function) é um tipo particular de função objetivo que é usada para resumir, como uma única figura de mérito, o quão perto uma determinada solução de design está de atingir os objetivos definidos. As funções de adequação são usadas em programação genética e algoritmos genéticos para orientar as simulações em direção a soluções de arranjo ideais.

Wikipedia

Uma “architectural fitness function” deve proteger as diversas propriedades de um sistema de software na medida em que modificações, preferencialmente incrementais, são realizadas. De maneira objetiva, uma solução implementada deve ser submetida sob a perspectiva de diversas fitness functions para garantir que todas as adaptações realizadas não impactam no atingimento dos objetivos de negócio, restrições ou atributos de qualidade que suportam. Toda vez que uma fitness function indicar afastamento do objetivo, sabe-se que há um problema a analisar ou adaptação a rever na arquitetura.

Um exemplo de fitness function são as medidas de response time de um serviço. Afinal, trata-se de expressão objetiva da performance (um dos diversos atributos de qualidade possível). Dependendo da “gravidade” a medição de fitness functions poderá ser realizada nos ambientes de desenvolvimento, homologação e produção.
0
Você concorda?x

A manutenabilidade de um código-fonte, outro atributo de qualidade, pode ser avaliada utilizando uma fitness function que “pondera” sobre diversas outras, como cobertura por testes, índices de acoplamento e outras métricas fornecidas por ferramentas de análise estática.
0
Você concorda?x

A qualidade das integrações de um sistema pode ser avaliada com uma fitness function que avalie a quantidade de implementações realizadas contract models (uma medida estática), ou ainda, o respeito aos contratos estabelecidos (uma medida dinâmica).
0
Você concorda?x

Adequação jurídica das licenças dos softwares consumidos por um sistema de software pode ser determinada por uma fitness function que verifique, em cada atualização, se os contratos foram alterados e “acionando advogados” quando necessário.
0
Você concorda?x

Cada architectural fitness function consiste em uma decisão arquitetural importante, que precisa ser devidamente registrada em uma ADR.
0
Você concorda?x

Toda grande jornada tem desvios, atalhos e … aprendizado

Os sistemas mais interessantes (e úteis) costumam começar com uma excelente direção, mas, raramente escopo claramente delimitado. Se há uma certeza é de que requisitos mudam, condições técnicas também.

Arquiteturas de software de qualidade são, acima de tudo, aquelas que permitem que mudanças de rumo sejam feitas com menos trauma possível. Quanto mais “fácil de mudar”, maior o espaço entre eventuais descontinuidades.

// TODO

Antes de avançar para o próximo capítulo, recomendo as seguintes reflexoões:

  • É possível expressar objetivos, atributos de qualidade e restrições do sistema em que está trabalhando de forma objetiva?
  • As métricas de qualidade interna estão orientadas a facilitar a manutenabilidade?
  • Quais partes do seu sistema demandam mais testes?
  • Qual o nível de acoplamento atual do frontend com lógicas de negócio?

Referências bibliográficas

FORD, Neal; PARSONS, Rebecca; KUA, Patrick. Building Evolutionary Architectures: support constant change. Gravenstein Highway North, Ca: O’Reilly Media, Inc, 2017.

MUNROE, Randall. Fixing problems. Disponível em: https://xkcd.com/1739/. Acesso em: 22 abr. 2021.

MUNROE, Randall. Standards. Disponível em: https://xkcd.com/927/. Acesso em: 22 abr. 2021.

MUNROE, Randall. The general problem. Disponível em: https://xkcd.com/974/. Acesso em: 22 abr. 2021.

HANSELMAN, Scott. Exiting The Zone of Pain: static analysis with ndepend. Static Analysis with NDepend. 2007. Disponível em: https://exco.me/ndepend Acesso em: 22 abr. 2021.

PAIVA, Fernando. Quatro práticas equivocadas que dificultam a modernização de sistemas corporativos legados. 2019. Disponível em: https://exco.me/legado. Acesso em: 22 abr. 2021.

WIKIPEDIA. Fitness Function. Disponível em: https://exco.me/fitness. Acesso em: 22 abr. 2021.

Compartilhe este capítulo:

Compartilhe:

Comentários

Participe da construção deste capítulo deixando seu comentário:

Inscrever-se
Notify of
guest
0 Comentários
Feedbacks interativos
Ver todos os comentários

Fundador e CEO da EximiaCo, atua como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Mentoria

para arquitetos de software

Imersão, em grupo, supervisionada por Elemar Júnior, onde serão discutidos tópicos avançados de arquitetura de software, extraídos de cenários reais, com ênfase em systems design.

Consultoria e Assessoria em

Arquitetura de Software

EximiaCo oferece a alocação de um Arquiteto de Software em sua empresa para orientar seu time no uso das melhores práticas de arquitetura para projetar a evolução consistente de suas aplicações.

ElemarJúnior

Fundador e CEO da EximiaCo, atua como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

+55 51 99942-0609 |  contato@eximia.co

+55 51 99942-0609  contato@eximia.co

0
Quero saber a sua opinião, deixe seu comentáriox
()
x