Minhas Abstrações Esconderam as Coisas que Eu Precisava Enxergar

Eu adoro uma abstração limpa. Há um prazer estético genuíno em pegar algo bagunçado e complicado e envolvê-lo em uma interface arrumada que esconde a bagunça, para que você possa pensar em um nível mais alto e esquecer os detalhes por baixo. Por isso eu recorria a abstrações o tempo todo — cedo, com entusiasmo e em excesso. E em um número surpreendente dessas vezes, a abstração à qual recorri não gerenciou a complexidade de forma alguma. Ela escondeu exatamente as coisas que eu mais precisava enxergar, e me cobrou uma nova camada de confusão pelo privilégio.

Essa foi uma lição difícil justamente porque a abstração é genuinamente boa e genuinamente poderosa. O erro não foi usá-la. O erro foi usá-la de forma errada, e confundir meu amor pela superfície limpa com bom discernimento de engenharia.

O que uma boa abstração deveria fazer

Vale a pena deixar claro para que serve a abstração, porque toda a falha é uma distorção de algo real. Uma boa abstração esconde o detalhe sobre o qual você não precisa pensar agora, para que você possa raciocinar em um nível mais alto sem segurar a bagunça inteira na cabeça de uma só vez. É uma das ferramentas mais poderosas de toda a engenharia — possivelmente a ferramenta, aquilo que permite construir sistemas complexos demais para serem compreendidos de uma vez.

Quando uma abstração funciona, ela é quase invisível. Você a usa sem pensar no que há por baixo, do mesmo jeito que dirige um carro sem pensar na combustão. Ela libera sua atenção limitada para o nível com o qual você realmente se importa. Esse é o sonho, e é um bom sonho, e é real. É também exatamente o que torna o modo de falha tão sedutor: toda abstração promete isso, e apenas algumas cumprem.

O que a abstração errada faz no lugar

Uma abstração ruim faz o oposto da boa, e o faz parecendo quase idêntica vista de fora. Em vez de esconder o detalhe de que você não precisa, ela esconde o detalhe de que você precisa. Ela traça sua fronteira no lugar errado, de modo que justamente as coisas sobre as quais você precisa raciocinar acabam do outro lado de um muro que você mesmo construiu, subitamente fora de alcance.

E comete um segundo pecado em cima do primeiro. Ela não remove de fato a complexidade subjacente — essa complexidade continua ali, intacta, fazendo seu trabalho por baixo da superfície. A abstração apenas adiciona uma nova camada sobre ela. Então agora, em vez de uma coisa complicada para entender, você tem duas: a realidade bagunçada por baixo e a abstração não-exatamente-certa que você sobrepôs a ela, mais a relação sempre confusa entre as duas. Você se propôs a reduzir o que tinha que pensar e conseguiu aumentar.

Abstração prematura: comprometer-se antes de entender

A forma mais comum do meu erro era abstrair cedo demais. Eu construía a estrutura limpa, geral e elegante antes de realmente entender o problema bem o suficiente para saber qual era sequer a estrutura certa. Parecia design bom e visionário. Geralmente era o oposto.

Uma abstração é, fundamentalmente, um compromisso com um formato específico — uma decisão sobre onde ficam as fronteiras, o que é escondido e o que é exposto, como as peças se relacionam. E comprometer-se com um formato antes de entender aquilo que você está moldando é uma maneira confiável de fixar o formato errado. Pior, uma vez que ela está no lugar, você começa a construir em cima dela, e cada nova coisa que você constrói aprofunda seu investimento em uma estrutura que foi adivinhada em vez de aprendida. A abstração prematura não corre apenas o risco de estar errada; ela ativamente entrincheira o próprio erro.

Abstrações que vazam fazem você depurar duas coisas

Há um tormento especial reservado às abstrações que escondem de forma imperfeita — aquelas que quase sempre funcionam, até deixarem de funcionar. Quando algo dá errado lá embaixo, na realidade que a abstração deveria ocultar, o vazamento força você a entender as duas camadas ao mesmo tempo: a superfície limpa em que lhe prometeram que você poderia pensar, e a bagunça por baixo que ela não conseguiu esconder por completo.

Isso é exaustivo de um jeito único. O propósito inteiro da abstração era deixar você pensar em uma só coisa. Agora uma falha o arrastou a pensar em duas, mais o mapeamento entre elas, mais a questão de em qual camada o bug realmente vive. Você está depurando a abstração e aquilo que ela abstrai simultaneamente, e a abstração, que deveria estar ajudando, agora é um obstáculo a mais entre você e o problema. Uma abstração que vaza pode ser pior do que nenhuma abstração, porque pelo menos sem abstração você tinha apenas uma camada para confundi-lo.

O custo de uma camada de que você não precisava

Aquilo que eu não havia contabilizado direito é que toda camada de abstração também é uma camada de indireção — mais uma coisa entre você e o que está de fato acontecendo. Quando tudo está funcionando, essa distância é o benefício; é o que permite você não pensar no nível mais baixo. Mas no momento em que você precisa entender ou depurar, essa mesma distância vira puro custo. Cada camada é mais um lugar onde você tem que olhar, mais uma tradução que tem que fazer na cabeça, mais um local candidato a esconder o problema.

Portanto, uma abstração que não se paga de verdade não é neutra. Ela é um imposto permanente, cobrado toda vez que você precisa raciocinar sobre o sistema, taxado em troca de uma conveniência da qual, no fim, você não precisava. Eu vinha adicionando esses impostos com entusiasmo, encantado pelas superfícies limpas, sem perceber que estava pagando pela maioria deles e me beneficiando de apenas alguns.

Conquiste suas abstrações a partir do concreto

A disciplina que finalmente ajudou foi quase o inverso do meu instinto. Não imponha abstrações lá no início, a partir de um palpite sobre o que você acabará precisando. Conquiste-as, a partir de experiência concreta e repetida. Construa a coisa específica, feia e particular algumas vezes primeiro. Sinta onde estão as costuras reais — onde as fronteiras naturais de fato caem, quais detalhes genuinamente se agrupam e quais não. E só então, depois que a realidade lhe mostrou suas juntas, abstraia ao longo das linhas que ela de fato traçou.

A boa abstração, vim a entender, é descoberta a partir do concreto, não imposta sobre ele. Ela é uma compressão de coisas que você já entende profundamente, não um atalho para contornar o entendimento delas. As que construí dessa forma — tarde, com relutância, depois que o concreto me ensinou onde elas pertenciam — foram as que de fato se sustentaram. As que construí cedo, por esperteza e estética, foram as que passei os meses seguintes combatendo.

A lição mais profunda: a abstração gerencia a complexidade, ela não substitui o entendimento

Tudo se reduz a uma confusão sobre para que serve a abstração. Eu vinha recorrendo a ela como um substituto para entender o problema — como se uma interface limpa pudesse me deixar pular a parte difícil de realmente compreender a coisa bagunçada por baixo. Não pode. A abstração é uma ferramenta para gerenciar a complexidade que você já entende, não para evitar o trabalho de entendê-la.

Você não consegue abstrair seu caminho para fora de não entender algo. Você só consegue esconder a própria confusão sob uma superfície de aparência mais arrumada, onde ela vai esperar pacientemente para emboscá-lo mais tarde, agora vestindo uma interface limpa. Entenda a coisa primeiro. Abstraia depois. E quando o fizer, trace as fronteiras ao longo das costuras que o entendimento revelou, não daquelas que apenas pareciam elegantes antes de você saber onde qualquer coisa de fato estava.

— Sem sinais, sem retornos, isto não é recomendação de investimento.