Não estava falando de maneira pejorativa ao dizer “teórico”. A teoria é ótima e ela ajuda muito no desenvolvimento.
Mas a teoria procura ser abrangente e, muitas vezes, procura resolver problemas de ocorrência rara. E na prática, realmente, podemos abrir mão de um pouco de purismo para buscar outros benefícios, como um design mais simples.
Bem, a pergunta um é tema de ampla discussão pela humanidade. Aliás, foi até um tanto capiciosa de sua parte, pois você sabe que não há uma resposta concreta. O que temos são definições de complexidade, dadas por diversos autores.
E eu concordo com você. Algumas pessoas podem tentar usar esse comentário para justificar o uso de um anti-pattern, que é o caso de muita gente que faz isso aqui no GUJ.
Mas esse não foi o único argumento que dei e nem de longe quero que fique justificado o uso de uma gambiarra ou de um anti-pattern.
Mas quando um pattern se torna um anti-pattern? Quando ele é usado fora de seu contexto. E é sobre isso que se tratava o meu post. Avaliar corretamente o contexto, não necessariamente justificar um anti-pattern.
Eu estava me referindo justamente a forma como muitos patterns são “vendidos”, especialmente pelos fabricantes de frameworks. Vende-se o pattern como se fosse a solução de todos os problemas. Muitos posts do GUJ usam o mesmo argumento: Troque singleton por dependency injection e durma tranquilo. Não estou falando que é o seu caso, aliás, bem pelo contrário. Gosto muito dos seus posts.
Sim, mas meu post foi sobre trade-offs. Trocar um padrão por outro sempre representa ganhos de um lado e perdas de outro. Usar um framework também. Era isso que eu queria ressaltar. E são esses os trade-offs que devem ser avaliados.
Foi o que ressaltei no exemplo do framework. Você tem que estar ciente que está se baseando em códigos de terceiros e tem que estar ciente das implicações disso. Se o framework usa reflexão, você tem que estar preparado para erros em runtime. É sua responsabilidade, como analista ou projetista de software, avaliar o impacto disso no sistema e o transtorno que isso causa a equipe.
O caso do “simples Registry e de Factories”, é um bom exemplo. Você ainda terá que se incomodar que suas factories sejam thread-safe e operem de maneira semelhante em múltiplos classloaders. Ou você terá o mesmo problema do bom e velho singleton. Daí eu ter dito que, se seu argumento era aquele, você fatalmente recairá num framework que faça isso para você, ou gastará horas desenvolvendo algo que está fora da lógica de seu negócio, ou correrá o risco. Mas deve-se pensar. Essa minha preocupação é relevante? Preciso mesmo garantir thread-safety nesse sistema? Ele roda em múltiplos class loaders?
Sim, eu concordo. Se você tiver duas instâncias de um singleton é um problema sério. Isso foi uma coisa que nunca defendi e até dei algumas situações onde o singleton certamente não se aplica, pois as chances de isso ocorrer são bastante altas.
Esse seu último paragrafo resumiu com maestria tudo o que eu vinha dizendo. Usar corretamente qualquer pattern envolve muito estudo, domínio do problema, entendimento dos requisitos técnicos e não técnicos, uso adequado de soluções provisórias e de longo prazo, organização e uma boa dose de disciplina. Em resumo, é necessário conhecer o pattern, seu impacto sobre todos os fatores que você colocou, dentro do sistema que você está desenvolvendo.