Uma das ideias que tenho amadurecido ao longo dos últimos anos está ligado às implementações de mecanismos arquiteturais e abstrações.
Em Abstrações – Tradeoffs e co-responsabilidade eu falei sobre o que são abstrações boas, abstrações ruins, ponderei sobre quando criá-las e o que ela tem de ter para ser considerada eficiente e eficaz.
Ao mesmo passo no evento Modelagem de Frameworks e Abstrações no canal .NET eu mostrei algumas decisões que encontramos em alguns frameworks importantes e vimos como essas decisões levam em conta a experiência de quem consome essas abstrações.
Nesses textos eu trabalhei o conceito de abstração. Hoje vou contar a história de como eu tenho pensado sobre o processo de evolução dessas abstrações.
Objetivos
O primeiro ponto é entender o que queremos com as abstrações e quais são seus objetivos:
Centralização
Unificar a forma como determinado recurso é acessado, garantir que pré e pós condições sejam executadas 100% do tempo, ter um único ponto de falha, um único ponto de testes. Tudo isso facilita a comunicação, entregando clareza sobre o que deve ser feito e como deve ser feito.
Deduplicação
Embora a centralização nos dê esse benefício, a deduplicação é um objetivo em si. Código duplicado, ou comportamentos parecidos em abstrações parecidas produzem confusão, além de dificultar a gestão e facilmente proliferar bugs.
Simplicidade e Facilidade
Essas abstrações simplificam um universo ilimitado de possibilidades em um subset propositalmente limitado de acordo com as ambições do projeto OU DA ABSTRAÇÃO EM SI. Embora sua função primária seja atender ao projeto, ela é um ser vivo com ambições próprias e por isso ela não atende ao projeto de qualquer maneira e a qualquer custo.
Standardização
Endereçar soluções comuns para problemas comuns é uma excelente forma de facilitar a comunicação, definindo claramente o que é correto na resolução dos problemas do cotidiano.
A evolução
Toda abstração tem como último estágio de maturidade se tornar algo corporativo e pode até mesmo extrapolar os âmbitos da própria empresa, talvez ser a fagulha que culmina no nascimento de outra empresa. Esse é um propósito quase que metafísico para as abstrações: expandirem seu horizontes.
Mas na minha opinião toda abstração deveria começar bem pequena, com uma visão bem limitada de sua atuação. Isso gera trade-offs. Não é incomum as primeiras versões assumirem responsabilidades equivocadas e serem projetadas para operar como parte do negócio. São erros e mais erros de design que demandam acertos e lapidação.
Mas a evolução natural é a correção desses equívocos, produzindo novas abstrações ou movendo parte do código para outros lugares que colaborem melhor com a abstração. Ela em si, não é objetivo do teu projeto, mas como um ser, possui identidade própria.
Mas aí vem o problema do crescimento. Como lidar com uma abstração que cresceu muito? Como lidar com a distribuição dessa abstração em diversos projetos.
Distribuição
É esperado que quando você gosta de uma abstração, que você a carregue para outros projetos. Basta você encontrar ganhos desproporcionais (ganhos muito maiores que as perdas) para sentir-se motivado a usá-la no próximo projeto. A mágica do reaproveitamento está aí.
Aí você precisa pensar: Criar um fork? Promover a uma library? Entregar para alguma equipe que centralize essas abstrações e libraries?
Uma proposta baseado na nossa organização geopolítica
Uma das formas que tenho elaborado nos últimos anos é uma ideia de abstrações locais, regionais e globais. A abstração começa regional, mas desde sempre com ambição de se tornar algo global. Mas não quero definir o que pode ser esse “global”. Enquanto regional, está claro que estamos falando do projeto. É seu primeiro beneficiário direto.
Marcos de maturidade e estabilidade precisam ser definidos para seja promovida a uma abstração regional, atendendo a alguns projetos. Isso fará com que ela ganhe corpo, aumentando seu escopo, ou melhorando seu design.
Mais uma vez precisamos definir outro nível de maturidade e estabilidade no nível regional para promover aquilo a global.
Esse processo de obtenção de maturidade com base na adoção e estabilidade de seus requisitos, ajuda na consolidação da solução como algo que realmente traz valor aos projetos.
E por fim, forks não são permitidos por padrão.
0 comentários