Effective Java: C#, 1. Considera usar métodos factoría estáticos en lugar de constructores
Efectivamente, los métodos factoría estáticos presentan ventajas claras frente a los constructores, tanto en Java como en C#. Google Collections, por ejemplo, usa intensivamente los métodos factoría estáticos. Entre sus ventajas:
- Puede usarse un nombre que indique el modo en que actúa la factoría, o partir de qué (tipos de) datos opera.
- Pueden reciclar memoria (usar algún tipo de cache), ya que no están obligados a devolver una instancia nueva.
- Pueden devolver instancias de subclasses de aquella de la que el método factoría estático forma parte.
- Eliminan la verbosidad cuando se usan tipos genéricos. (En todo caso, esa reducción de verbosidad se beneficia del borrado –erasure- de tipos en que se apoya el sistema de genéricos de Java, y parece un poco chapucero (o, cuando menos, poco elegante).
Y entre las limitaciones tenemos:
- Las clases sin constructores protegidos o públicos no pueden “subclasarse”, y a fin de cuentas la directriz propone suprimir estos tipos de constructor para promover los métodos factoría estáticos.
- No destacan en la documentación suficientemente, es decir, son indistinguibles de otros métodos estáticos.
Las ventajas 1, 2 y 3 de Java también lo son de C#. Nada que objetar. Pero la cuarta ventaja es irrelevante en C#. La verbosidad suele reducirse gracias al mecanismo de inferencia de tipos accesible con la palabra reservada “var”.
C#, con su uso de las clausuras (funciones anónimas) lleva más lejos la idea del uso de métodos factoría. Gracias a ellas, no es necesario definirlas como métodos estáticos: podemos definirlas al vuelo allí donde sean necesarias. Si es menester pasar a un método una factoría que devuelve una cola circular a partir de su capacidad, podríamos usar como argumento una lambda función ad hoc:
void NecesitoConstruirUnaColaCircular(Func creaColaCircular)
{
var colaCircular = creaColaCircular(100);
...
}
...
NecesitoConstruirUnaColaCircular(n => ColaCircular(n));
En el momento de invocar el método, definimos la factoría y la suministramos como argumento. El sistema permite reciclar una ColaCircular que ya tengamos:
var miCola = new ColaCircular(100); // Llamada 1 NecesitoConstruirUnaColaCircular(n => miCola); //Llamada 2 NecesitoConstruirUnaColaCircular(n => miCola);
Nótese que las dos llamadas usan la misma cola circular. Esto permite reducir las peticiones de memoria manejada.
El ejemplo que he puesto puede extenderse a funciones anónimas que devuelvan cualquier clase que implemente una interfaz, naturalmente, con lo que la factoría estática no tiene por qué depender de una clase. En Java no podemos hacer eso: el método estático deberá definirse en el cuerpos de una clase, nunca en el de una interfaz.
Esperemos que Java incorpore clausuras en la versión 7. Hoy no se entiende un lenguaje de programación que no las ofrezca.
Filed under: Effective Java: C# | Deja un comentario

No Responses Yet to “Effective Java: C#, 1. Considera usar métodos factoría estáticos en lugar de constructores”