Design Patterns: um mau sinal?

Uma semana atrás estava em Moçambique, próximo a África do Sul, ministrando três treinamentos da Caelum. Conheci muita gente e muitos desenvolvedores, incluindo dois escoceses: Cameron Smith, formado em ciências políticas (!) e mestre em engenharia de software pela Univerdade de Glasgow, e Colin Fairless, bacharel e mestre em Matemática Aplicada pela Imperial College de Londres. Posso dizer que aproveitei muito do enorme conhecimento desses dois.

Durante uma conversa com o Cameron, ele comentou bastante sobre a maneira de ensinar um novo desenvolvedor java. Em especial a dificuldade do HelloWorld e se os programadores são ainda iniciantes. Ele particularmente usa o beanshell no nício, para o estudante ter uma resposta rápida. Depois o assunto foi sobre como ensinar design patterns. Cameron criticou bastante jogar diagramas UML para uma pessoa e mostrar alguns casos de uso, como é feito em tantos livros. Tanto ele quanto eu achamos que isso deva ocorrer de uma maneira natural: esperar o aluno refletir sobre um caso particular. Um exemplo seria a necessidade de fazer algum cache ou controle de instância, para você deixar o construtor dessa classe privado e fornecer um método estático para fábrica-lo. Então sim você teria a permissão de explicar que milhares de pessoas passam por esse mesmo problema e que essa solução rápida foi batizada de factory. Neste início nada de UML, apenas código deve ser usado.

O amado e odiado Paul Graham diz, em a revanche dos nerds, que quando você encontra um problema e esse começa a se tornar comum, você tem três opções: (a) usar uma linguagem poderosa que lhe permita resolver aquele problema (b) escrever um interpretador para uma linguagem que resolva aquele problema (c) virar um compilador humano. Ele diz que os design patterns caem na categoria (c): é você quem precisa resolver um problema muito comum. Você é o responsável por perceber os casos de uso de determinado pattern e escrever pela milésima vez a mesma solução!

Ele ainda cita Peter Novig (um dos famosos autores do AIMA e diretor de pesquisas do Google), em sua apresentação sobre como 16 dos 23 design patterns do GoF são evitados/invisíveis usando linguagens dinâmicas.

Ambos criticam muito o uso de Design Patterns como um template: substitua aqui, ali e ali o nome de sua classe, implemente aquela interface e você já tem tudo quase pronto! Eles procuram separar isso de uma idéia que chamam de Design Strategies, fazendo uma analogia de templates versus provérbios: não é uma receita de bolo a ser aplicada, e sim mais um guia de como resolver um problema. A receita de bolo é o mau sinal! O smell.

Pensando nisso separei alguns design patterns que com o passar do tempo estão sumindo, devido a uma abordagem diferente de programação, ou até mesmo virando antipatterns.

Singleton – Este é bem fácil e já bloguei sobre os problemas do Singleton. É raríssimo querermos que uma classe possua uma única instância por modelagem. Normalmente usamos o singleton apenas para fazer lookup a uma instância: quase que uma variável global. Pode ser totalmente substituído com o uso de injeção de dependências.

Service Locator – Mesmo problema que o singleton: uma maneira de pegarmos a referência a algum objeto. O uso de injeção de dependências (como @EJB, @Resource e @PersistenceContext no Java EE 5) eliminam a necessidade de aplicar esse pattern.

ValueObject – No Java EE é comum criarmos classes que servem apenas para trafegar os valores das nossas entidades verdadeiras. Fazemos isso porque provavelmente nossas entidades são muito pesadas, remotas, ou fortemente acopladas a alguma API específica. Para passar essa informação para nossa camada View antes produzimos ValueObjects (ou Data Transfer Objects, para quem prefere). O Hibernate, EJB3 ou mesmo com os ActionForms do Struts eliminam a necessidade de você criar uma classe nova muita parecida com a sua entidade real, já que nessas tecnologias podemos usar POJOs.

DAO – Alguns dizem que não deveríamos ter um DAO: nossa própria entidade faria o acesso aos dados. É a idéia do ActiveRecord e de tantos outros frameworks (e para quem se lembra das ferramentas java de ORM do milênio passado, como Torque e OJB). Caso você tenha uma classe Produto, você teria um método estático Produto.list(), por exemplo. Isto evitaria o smell de criar uma hierarquia de classes paralelas a suas entidades. Pessoalmente hoje em dia eu não gosto da idéia, mas é uma forte vertente.

Obviamente não estou pregando a extinção dos patterns, apenas lembrando que devemos medir muito bem a necessidade de criar mais classes e mais abstrações, em vez de atacar o problema com mais simplicidade, como o Michael Nascimento também já blogou (duas vezes). Aproveite e conheça mais dos design patterns de maneira aplicada e coerente no nosso curso online.

8 Comentários

  1. Marcos de Sousa 19/12/2006 at 16:16 #

    Grande!!! Trabalhei temporariamente sob a custódia do Cameron num projecto, admiro muito a liderança dele e o trabalho que ele faz. Sou um fã do Cameron.

    Marcos de Sousa

  2. Cameron Smith 20/12/2006 at 04:31 #

    Oi Paulo e Marcos. Um post interessante. Só para dar mais uma indicação da maneira que “Design Patterns” são ganhando “mindshare”, enquanto deixam para trás qualquer noção da necessidade de /desenhar e ENTENDER/ seu programa, vejam esse livro, que analisei da última vez que tava no U.K.: http://www.amazon.co.uk/gp/product/0596007124

    Em termos pedagógicos, o livro é de alta qualidade: tem diagramas, exemplos, exercícios, uma maneira de explicar bem clara etc. Só que: em qual momento você vai contratar um programador que pensa que “design” é copiar as receitas deste livro e implenta-los, com passos de bebé, no sistema?

    Além disso, a loirinha na capa não tem nada a ver com o livro!!!

  3. Paulo Silveira 20/12/2006 at 11:24 #

    Achei um link interessante sobre singleton:
    http://steve.yegge.googlepages.com/singleton-considered-stupid

  4. João Paulo (neófito) 21/12/2006 at 09:53 #

    O livro citado é muito bom e didático. O problema é que “design” é diferente de “design patterns”. Design são as bases de projeto de software OO, e design patterns são soluções de design comprovadas. Antes de se aprender patterns, deve-se aprender design. É nisso que consiste o erro da maioria dos desenvolvedores que aprendem patterns hoje em dia. O passo “aprender design” é pulado, esquecido. Outro ponto é a necessidade do uso dos patterns. Abstração tem um custo, e deve ser usada somente quando necessária.

    Para aprender design antes dos patterns propriamente ditos, recomendo o livro , do Craig Larman, que é uma introdução ao projeto de software OO. Lá ele destaca a nessecidade de saber quando e por que usar patterns.

  5. João Paulo (neófito) 21/12/2006 at 09:57 #

    Desculpem o erro. O livro ao qual eu me refiro é o Applying UML and Patterns, 3rd Edition, do Craig Larman.

  6. Dias 03/01/2007 at 06:11 #

    Opa! Uma duvida sobre o Value Object… se é necessário retornar do POJO para o controller ou uma view qualquer uma entidade e mais algum objeto ou variáveis, qual seria a alternativa sem um VO ou DTO, como queira.

    Parabens pelo Blog, ótimos posts.

    Abraço

  7. Marcio Muzzi 28/07/2008 at 16:29 #

    Olá Paulo, antes de tudo parabéns pelo artigo!

    Gostaria que você compartilhasse sua opinião sobre um problema que passei na prática. Num sistema, construído em PHP, onde dei manutenção evolutiva por alguns meses, havia cerca 30 classes de acesso a banco (alocadas no pacote dao).

    Todas as classes dao utilizavam uma instância da AdoDb (http://adodb.sourceforge.net). Surgiu a necessidade de substituir a AdoDb pela PDO (www.php.net/pdo).

    A primeira solução, logo descartada, era de alterar todas as 30 classes dao para utilizarem os métodos da PDO. A segunda solução, proposta por mim, foi utilizar o padrão Adapter.

    Criamos uma classe chamada “PdoAdapter” contendo métodos com assinaturas idênticas às da classe AdoDb. As classes dao passaram a utilizar a classe adaptadora, dispensando assim qualquer alteração nelas.

    Neste caso, segui exatamente o que os fãs dos padrões de projeto defendem, e que aparentemente foi a melhor solução, concorda? Você recomendaria outra solução melhor ao invés de utilizar um design pattern?

  8. Paulo Silveira 28/07/2008 at 16:50 #

    Ola Marcio. De maneira alguma, o adapter foi muito bem aplicado nesse caso…
    Esse post só eta dando um alerta: muitas pessoas tentam encaixar um design pattern onde nao precisa, apenas pela questao de “usei um design pattern”. tambem quero mostrar que muitos deles hoje em dia ja podem ser anti patterns, e nao representar mais boas praticas, dada a evolucao da linguagem, frameworks e tecnolgoia

Deixe uma resposta