quinta-feira, 15 de março de 2012

Design Patterns: Singleton

O Design Pattern Singleton tem um dos desenhos mais simples. Ele tem como objetivo restringir a quantidade de instâncias de um tipo para apenas uma na aplicação. Ele faz isso controlando e centralizando a sua criação e o acesso a essa instância.

Imagine que você tenha um tipo que ocupa muito espaço na memória, ou que requer muitos recursos para ser instanciado. Se uma instância deste tipo puder ser reutilizada em diferentes lugares da aplicação, isso diminuiria o consumo de memória ou dos recursos consumidos para criação.

A descrição formal do Singleton é a seguinte: O Singleton garante que uma classe tenha apenas uma instância e fornece um ponto global de acesso a ela.

Um exemplo seria uma classe de geração de log. Dentro de uma aplicação, faria sentido haver apenas uma instância da classe responsável por escrever em um arquivo (ou base de dados) de log. Isso reduziria problemas de concorrência no acesso ao arquivo de log, pois a mesma seria tratada dentro do próprio Singleton, uma vez que haveria apenas uma única instância da classe de log acessando o arquivo.

Neste exemplo, teríamos o seguinte desenho:

Observe que temos o método construtor privado, o que não permite que a classe seja instanciada com o comando new por outras classes. Temos também um atributo estático que armazena a única instância de Log na aplicação, e o método ObterInstância() que retorna essa única instância.

O Singleton pode trazer problemas em alguns aspectos: ele pode ser um ponto de gargalo em aplicações que usam threads, devido à concorrência no acesso à instância única. Outro ponto que deve ser considerado: é interessante para a sua aplicação que o estado do objeto singleton seja compartilhado? Se não, você deve evitar o singleton, pois ele pode trazer problemas que serão difíceis de rastrear.

Baixe o código-fonte do exemplo em C# (requer o Visual Studio 2010)

Clique aqui para voltar à Intradução aos Design Patterns, com a lista de todos os Patterns apresentados.

sexta-feira, 9 de março de 2012

Design Patterns: Decorator

O Design Pattern Decorator tem como objetivo acrescentar responsabilidades a um objeto de forma dinâmica (em runtime), de forma mais flexível do que seria feito utilizando herança. O decorator permite que sejam criados vários comportamentos “adicionais” para um objeto e que eles sejam combinados conforme a necessidade da aplicação.

A descrição formal do Decorator é a seguinte: Anexa responsabilidades adicionais a um objeto dinamicamente. Decorators fornecem uma alternativa flexìvel à herança para extender as funcionalidades de um objeto.

Um exemplo clássico é a programação de janelas em aplicativos de interface gráfica. Imagine a janela como um objeto básico, nele os demais elementos gráficos são adicionados conforme a necessidade: barra de rolagem vertical, barra de rolagem horizontal, barras de menus, botões de maximizar, minimizar, etc. Cada um destes elementos gráficos seria uma “decoração” adicionada à janela, podendo ser combinados de acordo com a necessidade.

Um exemplo também comum e mais elucidativo é o sistema da cafeteria. Existem muitos tipos de café, combinandodiferentes ingredientes o preço do café muda. Em vez de criarmos uma nova classe para cada tipo de café, podemos usar o decorator para que, com um pequeno conjunto de classes, possamos representar todos os tipos de café servidos.

Baixe o código-fonte do exemplo (requer Visual Studio 2010).

Com este exemplo, podemos entender como os decorators estendem a funcionalidade básica da classe Café, e como todos eles implementam uma mesma interface, podem ser escolhidos e atribuídos em runtime, ou seja, dinamicamente.

Clique aqui para voltar à Intradução aos Design Patterns, com a lista de todos os Patterns apresentados.