Design Patterns Catalog

Simplificando o que não é complicado

Factory Method

O design pattern Factory Method define uma estratégia onde subclasses são responsáveis por criar objetos concretos utilizados por elas através de métodos definidos nelas mesmas.

Um exemplo do uso desse pattern pode ser dado em um framework para gerenciamento de aplicações web. Nesse framework o processamento de cada formulário da aplicação é executado por uma classe que implementa uma interface FormHandler e os dados do formulário - os valores nos campos dos formulários - são guardados por objetos que implementam uma segunda interface FormData, valendo observar que cada formulário executa uma ação diferente e cada formuário possui campos diferentes.

Ainda que o framework se utilize do FormHandler e do FormData concretos é necessário amarrar as duas classes entre si. Não queremos que a classe responsável pelas ações de um formulário de cadastro lide com uma classe com os dados de um formulário de “fale conosco”, por exemplo.

A solução para esse tipo de questão seria definir um método createFormData na interface FormHandler, responsável por retornar um objeto que implemente a interface FormData. Assim o FormHandler concreto será acionado pelo framework no momento em que o framework precisar de um objeto FormData, e o framework poderá sempre se utilizar de um FormData compatível com o FormHandler.

Utilizando o nosso exemplo do formulário do “fale conosco”, teríamos um ContactUsFormHandler implementando a interface FormHandler, cujo método createFormData vai retornar um ContactUsFormData, que é a implementação de FormData. O framework no momento da manipulação de um formulário irá instanciar o ContactUsFormHandler concreto e invocará o método createFormData que irá retornar um ContactUsFormData. Finalmente o framework poderá (por reflexão) popular o ContactUsFormData e invocar o método do FormHandler concreto que executará o processamento do formulário.

Factory Method Pattern - Diagrama de ClassesO framework se utiliza de FormHandler e FormData, mas não precisa saber que ContactUsFormHandler depende da implementação de FormData ContactUsFormData

Note que nessa abordagem garantimos a compatibilidade entre os objetos sem a necessidade de fazer com que o framework conheça as classes concretas envolvidas no processo (ele pode operar somente com as interfaces abstratas FormHandler e FormData).

Factory Method Pattern - Diagrama de Sequencia

De maneira mais direta o design pattern Factory Method indica a criação de um método createInstance (no exemplo um createFormData) na interface A responsável por retornar instâncias que implementam uma interface B a partir do momento em que um cliente (no nosso caso o framework) lide com A e B e a implementação de A cujo nome é C é compatível com uma implementação de B, que chamaremos de D (temos a interface A e a sua implementação C; temos a interface B e a sua implementação D). Assim o método createInstance de C irá retornar instâncias de D, ainda que o cliente continue enxergando somente As e Bs.

Ainda que o texto acima possa parecer confuso por ser abstrato demais, ele resume a essência do Abstract Factory.

Outro pattern que também tem relação com a criação de objetos compatíveis entre si de forma que isolada do restante do sistema é o Abstract Factory.