Atenção: esse artigo tem uma palestra complementar. Clique e assista!
Este artigo trata da aplicação prática de Design Patterns em problemas reais que enfrentamos no dia-a-dia. Construiremos um pequeno aplicativo orientado a objetos e ao longo do desenvolvimento implementaremos alguns design patterns para resolver problemas reais do sistema.
Para que serve
A aplicação de design patterns pode aumentar a qualidade de seus sistemas, pois se trata de soluções testadas e aprovadas para problemas comuns do desenvolvimento de software. Com o uso de Patterns você pode reduzir acoplamento, melhorar a legibilidade de seu código e aumentar o grau de reuso do mesmo.
Em que situação o tema é útil
Design Patterns são exatamente soluções para resolver problemas corriqueiros, ou seja, você pode usá-los a qualquer momento em seus projetos, seja na fase de desenvolvimento ou de manutenção, você pode se deparar com um problema que já fora analisado e solucionado antes.
Resumo do DevMan
Neste artigo nós desenvolveremos uma aplicação orientada a objetos e iremos aplicar diversos patterns ao longo deste desenvolvimento. Neste primeiro artigo nós começaremos vendo a aplicação do Singleton para uma classe de conexão com o banco de dados e para o objeto que representa nossa aplicação, além de vermos o uso de DAO’S para abstrair o acesso a dados e Factory para isolar a criação de objetos.
Os Design Patterns são padrões de design de soluções de software que já foram usados e aprovados para solucionar problemas comuns do desenvolvimento. Os Patterns mais famosos são os que foram catalogados no famoso livro conhecido como GOF (Gang Of Four). Apesar de esta literatura conter a descrição de 23 Patterns, não significa que os Design Patterns se limitam a este grupo. O uso destes Patterns, tanto os descritos no GOF quanto outros, contribui para o aumento da qualidade do nosso software, permitindo um menor grau de acoplamento, um maior reuso de código devido ao nível de abstração aplicado, uma maior coesão das classes e uma melhor legibilidade do código. Os Design Patterns são independentes de plataforma e tecnologia, sendo possível aplicá-los em qualquer linguagem orientada dos objetos. O conhecimento de orientação a objetos, por sinal, é algo imprescindível para a compreensão dos patterns.
Segundo o GOF, os Design Patterns são divididos em três categorias:
• Criacionais – Factory Method, Abstract Factory, Builder, Prototype, Singleton;
• Estruturais – Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy;
• Comportamentais –Interpreter, Template Method, Chain of Responsability, Command, Iterator, Mediator, Memento, Observer, State, Strategy, Visitor.
Hoje existe uma gama enorme de material sobre Design Patterns, porém é mais comum encontrar este material para Java e .Net, não é muito comum vermos exemplos de aplicações práticas de Design Patterns em aplicações Delphi. É exatamente isso que vamos tratar aqui, demonstrar de forma prática, como aplicar Design Patterns em problemas reais que podemos enfrentar diariamente em nossos projetos.
Primeiramente nós explicaremos os Patterns que usaremos e depois desenvolveremos uma aplicação simples e ao longo dela iremos implementar os Patterns pertinentes a cada tipo de problema. Aqui usaremos o Singleton para garantirmos apenas uma instância de nosso objeto Aplicacao e Conexao, o DAO para abstrair o acesso a dados do nosso sistema e a Factory para abstrair e isolar a criações de nossas DAO’s.
Singleton
De acordo com o GOF, o objetivo do Singleton é garantir que uma classe possua apenas uma instância dentro da sua aplicação e que esta instância possua um ponto de acesso global a todo o sistema. O Singleton precisa garantir que não teremos duas instâncias de um determinado objeto em nosso sistema. Como podemos notar na Figura 1, a implementação tradicional do Singleton prevê que haja um atributo privado e estático do tipo da classe, aqui no exemplo chamado de FInstance. Esse atributo é onde ficará a única instância de nosso objeto. Observe também que o construtor está privado, isso é necessário para que não seja possível criar instâncias deste objeto em qualquer lugar do sistema. O método GetInstance é o nosso ponto de acesso global à nossa instância. Veja na Listagem 1 a implementação em Delphi desta classe.
Figura 1. O padrão Singleton
Listagem 1. Implementação padrão do Singleton
unit UMySingleton;
interface
type
TMySingleton = class
private
class var FInstance:TMySingleton;
constructor create();
public
class function GetInstance():TMySingleton;
end;
implementation
{ TMySingleton }
constructor TMySingleton.create;
begin
inherited;
end;
class function TMySingleton.GetInstance: TMySingleton;
begin
//Verifica se a instância já foi criada
//caso não tenha sido, cria a mesma usando o construtor privado
if (not Assigned(FInstance)) then
FInstance := create;
//retorna a instância do Singleton
result := FInstance;
end;
end.
DAO – Data Access Objects
Data Access Objects, mais conhecido como DAO, visa separar toda a parte de acesso a dados em classes específicas para esta tarefa. Isso aumenta a coesão do código, já que separamos o modelo e sua regra de negócio dos códigos SQL para persistência e recuperação de dados do banco. Normalmente temos uma classe DAO para cada domínio da aplicação. Isso pode parecer ruim, pois aumentaríamos consideravelmente o número de classes do sistema. Mesmo assim a aplicação deste Pattern é interessante, pois mantemos centralizado em uma única classe todo o código de acesso a dados referente a um determinado modelo. Na aplicação do pattern DAO, os métodos para as operações CRUD recebem os objetos a serem persistidos como parâmetro, conforme ilustrado na ...