Opinião: Design Patterns são um péssimo nome
Introdução
Um dos meus hobbies, atualmente está sendo ler posts antigos, como os do blog AkitaOnRails. E em um de seus posts entitulados [ Design Patterns representam defeitos nas linguagens ]
Primeiramente, este é um bom post, muito bem embasado de acordo com o blog post Universe of Discourse
Mas, um dos pontos que me incomodou foi a mistura de Design do Software com Arquitetura de Software e a Ergonomia da linguagem.
Mas primeiramente vamos ver o que me incomodou em ambos os blog posts.
Na última vez que escrevi sobre design patterns, foi para apontar que embora o movimento tenha sido inspirado pelo trabalho de “linguagem de pattern” de Christopher Alexander, não é parecido com nada que Alexander tenha sugerido, e que de fato o que Alexander sugeriu é mais interessante e provavelmente teria sido mais útil para programadores do que o movimento de design pattern escolheu seguir.
Uma das coisas que eu apontei foi essencialmente o que Norvig disse: que muitos patterns não estão realmente endereçando problemas recorrentes de design em programas orientados a objetos. Eles estão, na realidade, endereçando deficiências em linguagens de programação orientadas a objetos e que em linguagens melhores, esses problemas simplemente não aparecem ou são resolvidos de maneira tão fácil e trivial que a solução não requer um pattern. Em linguagem assembly, “chamada de sub-rotina” pode ser um pattern; em C, a solução é escrever result = function(args …), que é simples demais para se qualificar como pattern. Em uma linguagem como Lisp ou Haskell ou mesmo Perl, com um bom tipo de lista e poderosas primitivas para operar em valores de listas, o pattern “Iterator” (iterador) é aliviado em um grande degrau ou tido como invisível. Henry G. Baker pegou esse ponto em seu artigo Iterators: Sinais de Fraqueza em Linguagens Orientadas a Objetos.
Recebi muitas mensagens sobre isso, e curiosamente, alguns chegaram à mesma conclusão da mesma forma: eles disseram que embora eu estivesse certo sobre Iterator, era um exemplo pobre porque era um pattern muito simples, mas que era impossível imaginar um pattern mais complexo como Model-View-Controller ser absorvido e se tornar invisível dessa maneira.
Obviamente, como um post antigo não vou dar muito trelo ainda mas, veja.
O motivo de conseguirmos enxergar um iterator
for (auto mp : m_children){
// Do anything
}
O incomodo
Sendo absorvido por uma linguagem, mas nunca um MVC é simplesmente uma diferença de escopo.
Uma coisa é você aprimorar a ergonomia da linguagem facilitando um método de escrita em detrimento de outro.
Outra coisa é pegar o modelamento da arquitetura e fazer uma linguagem com isso.
Imagine dentro do lex de uma linguagem, você tem print
que pertence a um view
e os parametros seriam models
com funções sendo controllers
.
Simplesmente estúpido ao máximo.
E qual o problema original…
Esse é um pequeno problema de usar o nome pattern
, sendo mais especifico design pattern
é muito pouco descritivo.
Eu estou falando do design
da linguagem para aumentar a produtividade do programador?
Ou estou falando do design
na arquitetura para melhorar legibilidade e manutenção do código ao todo?
O Model-View-Controller deveria se enquadrar em design pattern
então? SIM!!!
E Iteradores? SIM!!!
E Orientação a Objetos? SIM!!!
Isso porque novamente é um problema de nomeação e domínio. Se está tudo em um design pattern
então fica dificil fazer uma categorização mais aprofundada.
O mesmo serve quando colocamos software monolitico
contra microsserviços
.
Aqui temos dois padrões de arquitetura de software que de alguma forma também um padrão de design.
Podemos dizer que uma linguagem pode absorver uma arquitetura de software?
Uma solução
Podemos adjetivar o design pattern
para seu domínio.
Ergonic design pattern
para quando falamos de um padrão de arquitetura que pode ser absorvido pela linguagem.
Sendo um exemplo o Iterator
, Goto
, Function
.
Architecture design pattern
para quando falamos de um padrão de arquitetura que não pode ser absorvido pela linguagem, mas pelo software em geral.
Sendo exemplos: Model-View-Controler
, JSP Model1
, Model-View-Adapter
, Model-View-Presenter
Implementation design pattern
para quando falamos de um padrão de arquitetura que não pode ser absorvido pela linguagem, nem pelo software em geral mas colocado para facilitar a implementação.
Sendo exemplos: Strategy Pattern
, Observer pattern
, Servant pattern
, Command pattern
, Chain of responsibility pattern
.
Conclusão
No geral, o termo Design Pattern é genérico demais para ser útil no debate técnico.
Agrupando tudo desde ergonomia da linguagem até arquitetura distribuida sob o mesmo nome vira um deserviço.
A proposta de Adjetivar os patterns conforme seu domínio deve trazer clareza e distinguir melhor o que é arquitetural e o que é uma boa prática de implementação.
Talvez ao reclassificar os padrões com base não apenas naquilo que elas resolvem
mas também no lugar onde operam.