miércoles, 30 de abril de 2008

Factories en C++

Las implementaciones normales de factories en C++ suelen introducir la necesidad de modificar la clase Factory o su inicialización para cada clase que se agrega. Los intentos de evadir esta centralización utilizando la inicialización estática suelen ser algo como lo que aparece en el ejemplo factory_mal (es claro que hay algo mal :-) .

Este ejemplo utiliza la inicialización de variables globales para realizar el registro de los factory methods. En muchos casos esto parece funcionar, de hecho me acaba de funcionar al probarlo, pero contiene un error grave: asume un orden de inicialización de objetos estáticos entre distintos archivos (bueno, "unidades de traducción").

El problema en que no puede suponerse que los distintos Registrators vayan a inicializarse después que Factory::cm_. Si los Registrators se inicializan primero, Factory::registrate() accederá a un map no inicializado, probablemente llevando a un segmentation fault.

La solución a esto es la misma que la aplicada en el Singleton de Meyers: utilizar una variable estática dentro de un método. De este modo podemos garantizar que el objeto estará inicializado cuando sea utilizado.

Obviamente esta solución no maneja los problemas con múltiples threads, ni arregla mágicamente los problemas de diseño que puedan ser provocados por el uso indebido de singletons, pero soluciona el problema de la inicialización.

No hay comentarios: