Este patrón se utiliza cuando debemos generar distintas familias de objetos , dejando esto a la interface de la factory y sacándole dicha responsabilidad al cliente.
El cliente tan solo de dedica a crear un determinado tipo de objeto , mientras que la abstract factory se dedica a implementar y especificar a que familia pertenece el mismo .De esta forma podemos generar objetos del mismo tipo , pero generados desde distintas clases .O se tienen distintas implementaciones y estas son manejadas por la Factory.
El siguiente ejemplo , consta de una clase Abstract Factory que nos permite generar Empleados y Clientes .En base a esta clase generamos las Factory de Personas según la Empresa (mediante herencia), que estas serán las que implementen los métodos para crear las clases Clientes y Empleados .Cada una de estas Factory lo implementara según sus propias reglas .O sea acá es cuando la factory implementa el objeto según la familia que corresponda , sabiendo que siempre va a devolver un Cliente o Empleado , sin esto estar atado a la Empresa que lo genere .Esto hace que el cliente que consuma el factory solo se preocupa por instanciar la clase que necesite , mientras que la factory se encarga de la generación de la misma.
Codigo Clase Factory :
namespace AbstractFactoryPatternLibrary
{
public abstract class PersonaFactory
{
// Nos aseguramos de que todas las clases Factory van // a generar objetos del tipo Empleado y Cliente public abstract Empleado BuildEmpleado();
public abstract Cliente BuildCliente();
}
// Implementamos Abstract Factory // Mediante PersonaFactory sabemos los // objetos que debe generar la clase. // En este caso es una factory que lo implementa // segun los requerimientos de Empresa1 public class Empresa1PersonaFactory:PersonaFactory
{
// Implementamos los contructores que devuelven // los objetos establecidos en la Abstract Factory // En este caso se generan para el empleado tipo // EmpleadoEmpresa1 public override Empleado BuildEmpleado()
{
Empleado emp = new EmpleadoEmpresa1();
return emp;
}
public override Cliente BuildCliente()
{
Cliente cli = new ClienteEmpresa1();
return cli;
}
}
// Cumple el mismo proposito que Empresa2PersonaFactory. // Aca podemos ver como este pattern nos permite realizar // una implementacion distinta del primer Factory , generando // los mismos tipos de clases hacia el cliente , pero creandolo // desde otras clases. public class Empresa2PersonaFactory : PersonaFactory
{
public override Empleado BuildEmpleado()
{
Empleado emp = new EmpleadoEmpresa2();
return emp;
}
public override Cliente BuildCliente()
{
Cliente cli = new ClienteEmpresa2();
return cli;
}
}
public class ClienteEmpresa1:Cliente
{
public override void VerificarCuenta()
{
Console.WriteLine("Verificando Cuenta cliente Empresa1");
}
}
public class EmpleadoEmpresa1:Empleado
{
public override void CalcularSueldo()
{
Console.WriteLine("Calculando Sueldo empleado Empresa1");
}
}
public class ClienteEmpresa2:Cliente
{
public override void VerificarCuenta()
{
Console.WriteLine("Verificando Cuenta cliente Empresa2");
}
}
public class EmpleadoEmpresa2:Empleado
{
public override void CalcularSueldo()
{
Console.WriteLine("Calculando Sueldo empleado Empresa2");
}
}
// Clases abstract , van a ser las clases base// Desde donde van a heredar los Clientes y // Empleados de TODAS las Empresas. // De esta forma cada Empresa va a definir el // campo segun sus reglas de negocio. public abstract class Empleado
{
// Las clases van a tener que implementar este metodo
public abstract void CalcularSueldo();
}
public abstract class Cliente
{
public abstract void VerificarCuenta();
}
}
Codigo Aplicacion de Consola que consume nuestro Factory :
class Program
{
static void Main(string[] args)
{
// Generamos Factory de Personas para Empresa1 // mediante este objeto vamos a poder generar Clientes y Empleados // con la estructura que implementa la Empresa1 PersonaFactory personaFactoryEmpresa1 = new Empresa1PersonaFactory();
// Utilizamos la Factory para generar Clientes y Empleados Cliente clienteEmpresa1 = personaFactoryEmpresa1.BuildCliente();
Empleado empleadoEmpresa1 = personaFactoryEmpresa1.BuildEmpleado();
empleadoEmpresa1.CalcularSueldo();
// Factory para CLientes y Empleados del tipo Empresa2 PersonaFactory personaFactoryEmpresa2 = new Empresa2PersonaFactory();
//Generamos Clientes y Empleados para Empresa2 Cliente clienteEmpresa2 = personaFactoryEmpresa2.BuildCliente();
Empleado empleadoEmpresa2 = personaFactoryEmpresa2.BuildEmpleado();
clienteEmpresa2.VerificarCuenta();
empleadoEmpresa2.CalcularSueldo();
// Otro ejemplo // En la clase Gestor tenemos un metodo que no espera un Cliente // ni un Empleado.El mismo se encarga de Generarlos , tan solo nesesita // un objeto Factory. // Por lo que este Metodo queda abierto a que se le pueda pasar cualquier // Factory sin importar la Empresa Gestor miGestor = new Gestor();
miGestor.GenerarCliente(personaFactoryEmpresa1);
Console.ReadLine();
}
}
class Gestor
{
public void GenerarCliente(PersonaFactory persona)
{
Cliente cliente = persona.BuildCliente();
Console.WriteLine("Cliente Generado desde el Gestor");
}
}