Padrões de projeto em .NET: Factory Method
Também conhecido como Virtual Constructor, este padrão tem por objetivo definir uma interface para criar um objeto, mas deixar as subclasses decidirem que classe instanciar...
Padrões de projeto em .NET: Factory Method
Também conhecido como Virtual Constructor, este padrão tem por objetivo definir uma interface para criar um objeto, mas deixar as subclasses decidirem que classe instanciar. O Factory Method permite adiar a instanciação para subclasses.
Os frameworks usam classes abstratas para definir e manter relacionamentos entre objetos. Um framework é freqüentemente responsável também pela criação desses objetos.
Considere um framework para aplicações que possuem um cadastro de clientes. Duas abstrações-chave nesse framework são as classes Sistema e Cadastro. As duas classes são abstratas, e os clientes devem prover subclasses para realizar suas implementações específicas para a aplicação. Por exemplo, para criar uma aplicação para uma mecânica, definimos as classes SistemaMecanica e CadastroMecanica. A classe Sistema é responsável pela administração de Cadastros e irá criá-los conforme exigido – quando o usuário seleciona Consultar ou Novo, por exemplo, em um menu.
Uma vez que a subclasse Cadastro a ser instanciada é própria da aplicação específica, a classe Sistema não pode prever a subclasse de Cadastro a ser instanciada – a classe Sistema somente sabe quando um cadastro e não que tipo de Cadastro criar. Isso cria um dilema: o framework deve instanciar classes, mas ele somente tem conhecimento de classes abstratas, as quais não pode instanciar.
O padrão Factory Method oferece uma solução. Ele encapsula o conhecimento sobre a subclasse de Cadastro que deve ser criada e move este conhecimento para fora do framework.
As subclasses de Sistema redefinem uma operação abstrata CriarCadastro em Sistema para retornar a subclasse apropriada de Cadastro. Uma vez que uma subclasse de Sistema é instanciada, pode, então, instanciar Cadastros específicos da aplicação sem conhecer suas classes. Chamamos CriarCadastro um factory method porque ele é responsável pela “manufatura” de um objeto.
Quando usar Factory Method?
Use o padrão Factory Method quando:
- Uma classe não pode antecipar a classe de objetos que criam;
- Uma classe quer que suas subclasses especifiquem os objetos que criam;
- As classes delegam responsabilidade para uma dentre várias subclasses auxiliares, e você quer localizar o conhecimento de qual subclasse auxiliar que é a delegada
Estrutura
- Produto (Cadastro): define a interface de objetos que o método fábrica cria.
- ProdutoConcreto (MeuCadastro): implementa a interface de Produto.
- Criador (Sistema): declara o método fábrica, o qual retorna um objeto do tipo Produto. Criador também pode definir uma implementação por omissão do método factory que retorna por omissão um objeto ProdutoConcreto.
- CriadorConcreto (MeuSistema): redefine o método-fábrica para retornar a uma instância de um ProdutoConcreto.
Exemplo de código
Existem duas variedades principais para o padrão Factory Method. Na primeira, a classe Criador é uma classe abstrata e não fornece uma implementação para o método-fábrica que ela declara. Na segunda, Criador é uma classe concreta e fornece uma implementação por omissão para o método-fábrica. Também é possível ter uma classe abstrata que define uma implementação por omissão, mas isto é menos comum.
O primeiro caso exige subclasses para definir uma implementação porque não existe uma omissão razoável, assim contornando o dilema de ter que instanciar classes imprevisíveis. No segundo caso, o CriadorConcreto usa o método fábrica principalmente por razões de flexibilidade. Está seguindo uma regra que diz: “criar objetos numa operação separada de modo que subclasses possam redefinir a maneira como eles são criados”. Essa regra garante que projetistas de subclasses, caso necessário, possam mudar a classe de objetos que a classe ancestral instancia.
Vejamos, então, um exemplo para o segundo caso, em que o CriadorConcreto tem liberdade para definir o método-fábrica.
Public Interface Sistema
Function Criar(ByVal CadastroID As String) As Cadastro
End Interface
Public Class SistemaMecanica
Implements Sistema
Public Function Criar(ByVal CadastroID As String) As Cadastro _
Implements Sistema.Criar
If CadastroID.Trim.ToUpper.Equals("MECANICA") Then
Return New CadastroMecanica
ElseIf CadastroID.Trim.ToUpper.Equals("PADARIA") Then
Return New CadastroPadaria
End If
End Function
End Class
No próximo artigo estaremos discutindo outro padrão de criação: Prototype
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo