Rodrigo Allemand

Padrões de Projeto e Expressividade de Código

por Rodrigo Allemand em Mar.02, 2009, como Desenvolvimento

Quando eu comecei a vida de desenvolvedor, a minha idéia era que o divisor de águas era quem soubesse escrever “padrões de projeto”. Eu não estava completamente errado. Onde eu errei? Vamos lá…

Christopher Alexander, um renomado arquiteto italiano, uma vez citou:

Cadas padrão descreve um problema no nosso ambiente e o núcleo da sua solução, de tal forma que vc possa utilizar usar esta solução mais de um milhão de vezes, sem nunca faze-lo da mesma maneira.

Christopher Alexander não construia sistemas. Ele construia prédios, casas e cidades. Mas a citação acima se encaixa perfeitamente na definição de padrão de projeto para construção de sistemas! São soluções para um problema conhecido! Não adianta saber “fazer” um padrão de projeto. Vc precisa identificar o problema e achar a melhor solução para este problema, seja ela conforme o criador do padrão de projeto citou ou como você achar melhor. Basta que a definição do padrão seja seguida na sua implementação. Portanto, não grave como a sua classe deve ser para atender um determinado padrão, grave o que o padrão prega, o que ele se propõe a solucionar e os principios de design do padrão.

Outro grande problema encontrado é quanto a nomeção de classes. Quando se nomeia uma classe, deve-se deixar bem claro (porem sem termos um texto como nome) o que a classe faz e como ela foi idealizada. Não só com comentários, mas com os nomes claros, deixando-os entendíveis a primeira vista.

Essa é outra motivação dos padrões. A nomeação é tão importante como a sua implementação. Não adianta vc definir um padrão extremamente bem se uma pessoa que vai desenvolver utilizando essa classe, não conseguir enchergar o que ela realmente faz.

Imagine que vc está entrando em um projeto agora e ao abrir o seu workspace, se depara com uma Classe chamada ConfiguracaoSingleton. Automaticamente vc saberá que se trata de uma instância única da configuração da aplicação.

Ter expressividade no seu código é 80% de um código bem feito! Se alguem entende o que vc se propoz a fazer, as possiveis correções e manutenções (ou até mesmo, usar o seu código como exemplo) fica muito mais facil.

Portanto nomeie bem seu código e saiba o-que-resolve-o-que.

Obs: Vale a pena entender o que é um Anti-pattern tambem!

Para exemplificar melhor, vamos descrever um dos padrões mais conhecidos, mais e mais exemplificados e mais mal-entendidos da história do desenvolvimento orientado a objeto: o Singleton!

O Singleton foi originalmente criado pelo renomado grupo Gang Of Four [GoF], formado por Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides.  Sua definição é:

Garantir que uma classe tenha somente uma instância e fornecer um ponto global de acesso para a mesma.

Resumidamente, a motivação do Singleton é ter um ponto de acesso a uma intancia que seja unica para todo o sistema. As aplicações para este patterns são inúmeras: configuração, tratamento de informação compartilhada, parametrização, manter estado de um objeto, manter instancias de outros objetos que sejam statefull, etc. O qua vai guiar como contruir este objeto é a sua necessidade.

ATENÇÃO: Os códigos utilizados nestes exemplos são meramente ilustrativos.

Vamos ao exemplo mais conhecido de todos:

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

    public Singleton getInstance(){
        if(instance == null)
            instance = new Singleton();
        return instance;
    }

}

Este sem dúvidas é o código mais conhecido como Singleton. Mas ai começam os problemas…

Se eu tiver em um sistema muito concorrido, pode acontecer de duas instancias serem criadas ao mesmo tempo. Se isso for realmente um problema, refatorando o código poderemos ter algo como:

public class Singleton {

	private static Singleton instance = null;

	private Singleton() {
	}

	public synchronized Singleton getInstance(){
		if(instance == null)
			instance = new Singleton();
		return instance;
	}

}

Sincronizando o método, podemos garantir que apenas uma chamada será processada a cada momento. Mas isso torna o código muito ruim, já que até mesmo depois da criação, todas as chamadas deverão ser sincronizadas e, conforme dito no problema 1, a sua concorrência é grande, o que implica em muitos acessos e uma baixa performance desse método.

Se isso for realmente um problema, para solucionar podemos fazer coisas do tipo:

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

    public Singleton getInstance(){
        if(instance == null)
            synchronized (Singleton.class) {
                instance = new Singleton();
            }
        return instance;
    }

}

Beleza! com isso conseguimos garantir concorrência e performance, correto? Não, não não… sendo bem purista, ainda há uma possibilidade de haver uma concorrencia na linha 09 do último exemplo. Sim, é possível sim (Calma, são apenas exemplos, rs)! Se isso for um problema, refatorando um pouco mais, podemos ter um código assim:

public class Singleton {

    private static Singleton instance = null;

    private Singleton() {
    }

    public Singleton getInstance(){
        synchronized (Singleton.class) {
            if(instance == null)
                synchronized (Singleton.class) {
                    instance = new Singleton();
                }
        }
        return instance;
    }

}

Pronto! Temos um singleton!!!

Mas ainda temos um probleminha… E se o sistema tiver rolando em Cluster?! Se vc tiver mais de uma JVM, vão existir mais e uma instância do seu singleton, o que deixa de ser singleton!

Bem, perceberam que a ligação entre problema e solução não diz respeito a como codificar. Eu tenho vários exemplos de Singleton acima e até o momento eu não resolvi o meu problema, que é ter uma instância, que suporte concorrência, com performance e em um ambiente distribuido. E eu poderia fazer milhões de implementações diferentes para conseguir chegar ao meu objetivo!

Mas e se eu não me importasse de ter mais de uma instancia no Cluster? E se a minha concorrência fosse muito pequena a ponto de não atrapalhar a minha performance? Isso cabe a você!!! Como eu disse, conhecer o problema e dar a melhor solução possivel!

Existem todos os tipos de pessoas! Existem aqueles que pensam em uma solução, implementam um ou mais padrões sem ao menos conhecer o que está fazendo; como tambem existem aqueles que implementam vários padrões de projeto para um simples Hello World e mesmo assim, a implementação está errada!

Só para termos ideia, vou colocar mais um exemplo de Singleton. Neste eu utilizo o contexto de uma aplicação Web para individualizar a minha instancia.

public class Singleton {

    private static final String KEY = "singleton";

    private Singleton() {
    }

    public Singleton getInstance(ServletContext context){
        Object obj = null;
        obj = context.getAttribute(KEY);
        if(obj == null){
            synchronized (Singleton.class) {
                Singleton singleton = new Singleton();
                context.setAttribute(KEY, singleton);
                return singleton;
            }
        }
        return Singleton.class.cast(obj);
    }

}

Portanto, entender o seu problema, saber qual padrão de projeto aplicar e nomea-lo corretamente é o divisor de aguas.

Até!

Comente e Recomende!

:, , , ,
3 comentários para este post:
  1. André Faria Gomes

    É muito importante utilizar padrões, porque por serem amplamente conhecidos, realmente, tornam muito mais fácil a comunicação entre a equipe de desenvolvimento, mas o problema realmente acontece quando as pessoas querem aplicar padrões a todo custo, sem anda entender que problemas os padrões resolvem e quando realmente devem ser aplicados. Acho que você consegui sintetizar tudo isso muito bem em seu post. Parabéns, continue escrevendo.

  2. Bruno Larose

    Parabéns pelo blog, conteúdos interessantes.

    Pode me dizer qual componente do wordpress você utiliza para postar códigos ?

    Obrigado

  3. cleisson

    meus parabens!! excelente post!

Comente!

Procurando por algo?

Use o campo abaixo para procurar por todo o site:

Ainda não achou? Deixe um comentário ou me mande um email que eu cuido disso!

Minhas indicações!

Alguns blogs que eu recomendo...