אֵין כָּל חָדָשׁ תַּחַת הַשָּׁמֶשׁ ein kol chadash tachat hashemesh · nada há de novo sob o sol · Kohelet 1:9

Blog/Artigos · Engenharia

Design Patterns: nada há de novo, o problema recorrente tem forma conhecida

Os padrões da Gang of Four, as três categorias, o vocabulário compartilhado que eles criam e a armadilha de usar padrão onde não há problema.

Por Juliano Vince de Campos · · 8 min de leitura · 5 seções · 5 figuras

אֵין חָדָשׁ EIN · KOHELET 1:9

Kohelet, o mais desencantado dos livros, diz que nada há de novo sob o sol: o que foi é o que será, e o problema que hoje parece inédito já atormentou alguém antes. Em engenharia de software isso é libertador, não deprimente. O problema de projeto que você encara agora, como criar objetos sem acoplar ao tipo concreto, como notificar muitos quando um muda, como trocar um algoritmo em tempo de execução, já foi resolvido inúmeras vezes, e as boas soluções foram catalogadas. Design patterns são essas formas conhecidas: não código para copiar, mas soluções nomeadas para problemas que recorrem. Reconhecer que o problema não é novo é o primeiro passo para não reinventar, mal, a roda que já gira bem.

Soluções catalogadas para problemas que voltam

Em 1994, quatro autores, Gamma, Helm, Johnson e Vlissides, que ficaram conhecidos como a Gang of Four, publicaram um livro que catalogou vinte e três padrões de projeto orientado a objetos. A ideia veio da arquitetura de edifícios, de Christopher Alexander, que percebera que boas soluções de projeto se repetem e podem ser descritas como padrões reutilizáveis. Cada padrão do catálogo descreve um problema recorrente, a solução testada, e as consequências de aplicá-la. Não é código pronto; é a forma da solução, adaptável à sua linguagem e ao seu caso.

O valor está em não começar do zero diante de um problema estrutural conhecido. Quando você precisa garantir uma única instância de algo, existe o Singleton, com suas armadilhas conhecidas; quando precisa notificar vários interessados sobre uma mudança, existe o Observer; quando precisa trocar um comportamento em tempo de execução, existe o Strategy. Conhecer o catálogo é ter, na cabeça, um repertório de soluções provadas para os problemas que a orientação a objetos faz recorrer, e reconhecer o padrão certo no problema à frente é o que separa quem projeta com repertório de quem improvisa cada vez.

Figura 1As três categorias de padrões da Gang of Four
  • CRIACriacionaiscomo criar objetos sem acoplar ao tipo concreto
  • ESTREstruturaiscomo compor objetos em estruturas maiores
  • COMPComportamentaiscomo objetos colaboram e distribuem responsabilidade
  • EX1Factory, Buildercriacionais: fabricar sem revelar a classe concreta
  • EX2Adapter, Decoratorestruturais: adaptar e envolver sem herança rígida
  • EX3Observer, Strategycomportamentais: notificar muitos, trocar algoritmo
Vinte e três padrões em três categorias, catalogados pela Gang of Four em 1994. Cada um descreve um problema recorrente, a solução testada e suas consequências. Não é código pronto, é a forma da solução.

As três famílias, e o que cada uma resolve

Os padrões se dividem em três famílias pela natureza do problema que atacam. Os criacionais lidam com a criação de objetos, desacoplando o código de quem cria dos tipos concretos que ele instancia: o Factory Method e o Abstract Factory delegam a decisão de qual classe criar, o Builder monta objetos complexos passo a passo, o Singleton controla a instância única. Os estruturais lidam com a composição: o Adapter faz duas interfaces incompatíveis conversarem, o Decorator adiciona comportamento envolvendo o objeto sem herança, o Facade dá uma porta simples para um subsistema complexo.

Os comportamentais, a maior família, lidam com como os objetos colaboram e distribuem responsabilidade. O Observer notifica muitos interessados quando um sujeito muda, base de toda arquitetura orientada a eventos. O Strategy encapsula algoritmos intercambiáveis atrás de uma interface comum. O State faz um objeto mudar de comportamento conforme seu estado interno. O Command transforma uma requisição em objeto, permitindo fila, desfazer e log. Não é preciso decorar os vinte e três; é preciso entender as três famílias e reconhecer, diante de um problema, a que família ele pertence, porque isso já aponta para o punhado de padrões que valem consultar.

Figura 2Padrões clássicos por família, e o que resolvem
PadrãoFamíliaProblema que resolve
Factory Methodcriacionalcriar objeto sem acoplar à classe concreta
Buildercriacionalmontar objeto complexo passo a passo
Adapterestruturalfazer interfaces incompatíveis conversarem
Decoratorestruturaladicionar comportamento sem herança rígida
Observercomportamentalnotificar muitos quando um sujeito muda
Strategycomportamentaltrocar o algoritmo em tempo de execução
Não é preciso decorar os vinte e três. Entender as três famílias e reconhecer a que família o problema pertence já aponta para o punhado de padrões que valem consultar.

O maior valor não é o código, é o vocabulário

O ganho mais subestimado dos design patterns não está no código que eles produzem, está na linguagem que eles criam. Quando um engenheiro diz aqui eu usei um Observer, ou isto pede um Strategy, ou cuidado com esse Singleton, o time inteiro entende uma ideia complexa numa palavra. O padrão vira uma unidade de comunicação, um substantivo compartilhado que comprime um parágrafo de explicação em um termo. É o mesmo poder da linguagem ubíqua do DDD: nomear bem para pensar e comunicar melhor.

Sem esse vocabulário, cada discussão de design recomeça do chão, descrevendo a estrutura em detalhe toda vez. Com ele, a conversa opera num nível mais alto, e o code review fica mais rico: revisar deixa de ser só ler linhas e passa a ser reconhecer intenções nomeadas. É por isso que conhecer os padrões vale mesmo para quem raramente implementa um do zero: o valor de conseguir ler o código dos outros e das bibliotecas, que estão cheias deles, e de participar da conversa de arquitetura como quem fala a língua, supera o de escrever mais um Factory. Nada há de novo sob o sol, e ter nome para o que recorre é o que permite ao time construir sobre o conhecido em vez de redescobri-lo a cada projeto.

Figura 3O padrão como unidade de comunicação no time
  1. 01Sem vocabuláriocada discussão descreve a estrutura em detalhe, do zero
  2. 02Nomear o padrão'isto é um Observer' comprime um parágrafo numa palavra
  3. 03Conversa mais altaa arquitetura se discute em intenções, não em linhas
  4. 04IACode review mais ricorevisar vira reconhecer intenções nomeadas
  5. 05Ler o dos outrosbibliotecas e código alheio ficam legíveis pelo repertório

Ter nome para o que recorre permite construir sobre o conhecido, em vez de redescobri-lo a cada projeto. É o mesmo poder da linguagem ubíqua do DDD.

O maior valor dos padrões não é o código, é a linguagem. O padrão vira substantivo compartilhado, e a conversa de design opera num nível mais alto. Vale mesmo para quem raramente implementa um do zero.

A armadilha: padrão em busca de problema

O perigo dos design patterns é o entusiasmo. Quem acaba de aprender o catálogo tende a ver padrões em todo lugar e a aplicá-los onde não há problema que os justifique, o clássico cargo cult: reproduzir a forma sem entender a necessidade. O resultado é o código enfeitado de Factories, Strategies e Decorators que ninguém pediu, com camadas de indireção que só existem porque o padrão era conhecido, não porque o problema existia. Padrão aplicado sem problema é complexidade pura, e piora exatamente o que os padrões deveriam melhorar: a legibilidade e a facilidade de mudar.

A regra madura é que o padrão responde a um problema, não o contrário. Você não sai procurando onde encaixar um Visitor; você encontra um problema de projeto, reconhece que ele recorre, e lembra que existe uma solução conhecida para ele. O código mais simples que resolve o problema de hoje quase sempre vence o código elaborado que resolve o problema imaginado de amanhã. Design patterns são ferramentas na caixa, e a marca do artesão não é usar todas em cada peça, é escolher a certa para o corte à frente, e muitas vezes a ferramenta certa é a mão livre, sem padrão nenhum. Nada de novo sob o sol vale para os problemas; não é licença para inventar problema só para usar a solução.

Figura 4Quando o padrão ajuda: existe o problema contra a complexidade que ele adiciona
O problema que o padrão resolve existe de fato
Use o padrãoproblema real, complexidade justificada: a solução conhecida rende.
Use com parcimôniaproblema real, mas padrão pesado: veja se há solução mais simples antes.
Padrão leve, sem problemanão há problema, mas o padrão custa pouco: ainda assim, indireção à toa.
Cargo cultnão há problema e o padrão é pesado: complexidade pura, piora o que devia melhorar.
Complexidade que o padrão adiciona
O padrão responde a um problema, não o contrário. Aplicá-lo sem problema é cargo cult: reproduz a forma sem a necessidade. A marca do artesão é escolher a ferramenta certa, e às vezes é a mão livre.

A maturidade com padrões, e onde eles se apoiam

A relação com padrões amadurece em fases reconhecíveis. Primeiro o desconhecimento, reinventando soluções mal. Depois a descoberta empolgada, aplicando padrões em tudo, a fase do cargo cult. Então a reação, às vezes rejeitando padrões por inteiro depois de se queimar com o excesso. E por fim o julgamento: reconhecer o problema recorrente, saber que há solução conhecida, e aplicá-la com parcimônia, ou não aplicá-la, conforme a complexidade se justifique. O objetivo nunca foi usar padrões; foi resolver bem, e padrões são um meio entre outros.

Design patterns assentam sobre o SOLID, cujos princípios muitos padrões materializam, o Strategy é aberto-fechado em ação, o Observer é inversão de dependência, e sustentam o que vem por cima, a arquitetura limpa e o design orientado a eventos, feitos de padrões combinados. Mas a lição de Kohelet corta os dois jeitos: nada de novo sob o sol significa que a solução para o seu problema provavelmente já existe, e vale conhecê-la; e significa também que a moda de arquitetura que hoje parece revolucionária é, quase sempre, um padrão antigo com nome novo. Repertório sem dogma, reconhecer o velho no novo e a solução no problema, é o que a maturidade com padrões entrega.

Figura 5Maturidade na relação com design patterns
  1. 0Desconhecereinventa soluções, mal, a cada problema
  2. 1Descobreaprende o catálogo e se empolga
  3. 2Cargo cultaplica padrão em tudo, indireção sem problema
  4. 3Reagerejeita padrões por inteiro, queimado pelo excesso
  5. 4Julgareconhece o problema, aplica com parcimônia ou não aplica
  6. 5Repertório vivovê o velho no novo, a solução no problema, sem dogma
O objetivo nunca foi usar padrões, foi resolver bem. A fase 2, cargo cult, e a 3, rejeição, são passagens comuns. A maturidade é repertório sem dogma: reconhecer o velho no novo e a solução no problema.

Para levar

Design patterns partem de Kohelet: nada há de novo sob o sol, e o problema de projeto que parece inédito já foi resolvido e catalogado pela Gang of Four. As três famílias, criacionais, estruturais e comportamentais, dão soluções provadas, mas o maior valor é o vocabulário, o substantivo compartilhado que faz o time entender uma ideia numa palavra. A armadilha é o cargo cult, o padrão em busca de problema, e a maturidade é o repertório sem dogma. A IA reconhece o padrão e desmascara o excesso. O fim, porém, nunca foi usar padrões, foi resolver bem, e às vezes a ferramenta certa é a mão livre.

Tags

  • #julianovincedecampos
  • #DesignPatterns
  • #Engenharia
  • #GangOfFour
  • #OrientaçãoAObjetos
  • #Arquitetura
  • #DesignDeSoftware
Retrato de Juliano Vince de Campos

Quem escreve: Juliano Vince de Campos

Gerente de Operações, Tecnologia e Infraestrutura (SRE) numa central de registros. Trabalho com tecnologia desde 2009 e com cibersegurança em tempo integral desde 2015, em infraestrutura crítica, fintech e banking. Escrevo sobre o que eu opero: confiabilidade, segurança, governança e IA que passa por gate antes de chegar em produção.

Leia em seguida

Onde eu estudei, me certifiquei e trabalhei

  • University of Cambridge
  • PUC Minas
  • PUC-RS
  • PUC Goiás
  • Pontificia Universidad Católica del Perú
  • Amazon Web Services
  • Google
  • IBM
  • Oracle
  • COBIT 5 Foundation
  • ITIL v3 Foundation
  • Exemplar Global
  • Red Team Leaders
  • Infosec
  • Salesforce
  • Flowgrammers
  • ISO/IEC 27001
  • NIST Cybersecurity Framework
  • Compass UOL
  • Luby
  • Creditas
  • PicPay
  • PagoNxt, Santander
  • Mercado Pago
  • Itaú Unibanco
  • Foursys
  • Soluti Certificação Digital