C# - Padrão Factory Method (evitando o uso de if/else)
Neste artigo vamos continuar apresentando o padrão de projeto Factory Method. |
Continuando o artigo anterior vou mostrar uma forma de evitar o uso de blocos de código if/else ou switch/case na lógica de criação dos objetos.
Vamos usar como exemplo o projeto criado no artigo anterior.
E vamos focar nossa atenção na classe LancheFactory
cujo código é mostrado abaixo:
using ConsoleApp1.ConcreteProduct;
using ConsoleApp1.Creator;
namespace ConsoleApp1.ConcreteCreator
{
public class LancheFactory : LancheFactoryMethod
{
public override Lanche CriarLanche(int tipo)
{
if (tipo == 1)
{
return new Bauru();
}
else if (tipo == 2)
{
return new Frango();
}
else if (tipo == 3)
{
return new MistoQuente();
}
else if (tipo == 4)
{
return new Vegetariano();
}
else
{
throw new System.ArgumentException("Lanche não encontrada");
}
}
}
}
|
Embora a lógica de criação dos objetos relativos aos lanches concretos esteja agora encapsulada e centralizada em um único ponto do projeto, o que por si só facilita a manutenção do código, estamos usando no código um bloco if/else para decidir qual objeto criar com base no tipo selecionado.
Atualmente temos 4 lanches sendo instanciados mas imagine que você tenha 50 ou 100 lanches ?
Seguindo essa abordagem você teria que criar 50 ou 100 estruturas if/else ou swith/case o que pode ser cansativo.
Uma abordagem para resolver esse problema é usar uma classe Dictionary e armazenar no dicionário as instâncias que desejamos usar relacionando-as com os tipos de seleção que o usuário pode escolher.
Segundo esta abordagem o código da classe LancheFactory ficaria assim:
using ConsoleApp1.ConcreteProduct;
using ConsoleApp1.Creator;
using System;
using System.Collections.Generic;
namespace ConsoleApp1.ConcreteCreator
{
public class LancheFactory : LancheFactoryMethod
{
public override Lanche CriarLanche(int tipo)
{
var factory = LancheFactories[tipo];
return factory();
}
public static Dictionary<int, Func<Lanche>> LancheFactories =
new Dictionary<int, Func<Lanche>>
{
{ 1, ()=>new Bauru() },
{ 2, ()=>new Frango() },
{ 3, ()=>new MistoQuente()},
{ 4, ()=>new Vegetariano() },
};
}
}
|
Vamos entender o código:
Criamos um método estático chamado LancheFactories onde usamos a classe Dictionary que representa uma coleção de chaves e valores.
No código as chaves são os tipos dos lanches, no exemplo temos o tipo 1, 2, 3 e 4 e eles estão associados com a instância do Lanche específico.
Note que estamos usando Delegate Func<T> que representa um ponteiro para um método. No exemplo ao conforme o tipo selecionado será retornado uma instância do Lanche que foi associado.
Esta é uma forma bem simples de não usar o bloco if/else uma outra forma seria usar polimorfismo ou aplicar Reflection.
Pegue o código do projeto aqui : FactoryMethod2.zip
"Louvai ao SENHOR, porque ele é bom, porque a sua
benignidade dura para sempre."
Salmos 118:1
Referências:
NET - Unit of Work - Padrão Unidade de ...
NET - O padrão de projeto Decorator
NET - Padrão de Projeto Builder
C# - O Padrão Strategy (revisitado)
NET - O padrão de projeto Command
NET - Apresentando o padrão Repository