Padrão Abstract Factory

Veja neste artigo mais uma item da série de publicações sobre padrões de projetos, hoje falaremos sobre o padrão Abstract Factory.

Considere uma aplicação onde podemos ter múltiplas interfaces gráficas (a princípio apenas duas), devemos pensar em fazer isso da forma mais escalável possível, é aí que entra um padrão de Projeto: Abstract Factory.

Criaremos dois tipos de interfaces distintas: “KDE” e “Gnome”.

A ideia é que a aplicação não chame diretamente as classes concretas e que a adição ou remoção de um tipo de interface dê o menor trabalho possível, portanto vamos criar uma classe abstrata para que a classe cliente que necessitar de uma janela, por exemplo, não saiba se a janela é de “KDE” ou “Gnome”, ela tem de saber apenas que é uma janela.

Temos o seguinte diagrama:

As classes KDEFactory e GnomeFactory herdam de AbstractGui, ambas tem dependência da Classe AbstractJanela e AbstractBotao, porém não falaremos sobre isso agora.

A classe AbstractGui decidirá, em tempo de execução, qual a interface que deverá ser instanciada.

Temos então, os métodos sobrescritos nas duas classes-fábricas: CriarJanela() e CriarBotoes().

Caso em alguma dessas classes, ou até mesmo em outra que deva surgir, não haja a necessidade de mudança de comportamento padrão, a Classe AbstractGui possui um método padrão de criação de janelas e Botões.

A seguir, temos o seguinte diagrama:

Explicação: Cada Classe-Fábrica possui seus próprios botões e Janelas, herdando de AbstractBotao e AbstractJanela, pois assim, caso eu queira adicionar uma terceira interface com o nome “WindowMaker”, por exemplo, apenas criaria meu botão e minha janela nova, herdaria de AbstractBotao e AbstractJanela, respectivamente, e criaria um “WindowMakerFactory” herdando de AbstractGui.

O grande segredo está na classe AbstractGui, o Cliente chama apenas o método ObterInstancia() da classe referida, e esta, em tempo de execução, retorna, de acordo com algum contexto, uma instancia de KDE, Gnome ou outra futura interface implementada.

No método ObterInstancia(), teria algo equivalente a:

public static AbstractGuiObterInstancia() { switch(Constantes.Constantes.Tipo) { case"Gnome": returnnew GnomeFactory(); case"KDE": returnnew KDEFactory(); default: return null; } }

Poderia ser uma Sessão, um Id de algum contexto, algum critério que diferenciasse o seu tipo de interface.

Segue o diagrama final:

Com isso, deixamos o sistema escalável, de fácil manutenção, e com um nível baixo de acoplamento, visto que a Classe Cliente não sabe o que é KDE, ou Gnome, apenas o usa.

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados