En nuestras aplicaciones en su mayoría grandes, generalmente tenemos unas pocas ubicaciones para "constantes":
- Una clase para GUI y constantes internas (títulos de página de pestaña, títulos de cuadro de grupo, factores de cálculo, enumeraciones)
- Una clase para tablas y columnas de bases de datos (esta parte es código generado) más nombres legibles para ellas (asignadas manualmente)
- Una clase para mensajes de aplicación (registro, cuadros de mensaje, etc.)
Las constantes generalmente se separan en diferentes estructuras en esas clases. En nuestras aplicaciones C ++, las constantes solo se definen en el archivo .h y los valores se asignan en el archivo .cpp.
Una de las ventajas es que todas las cadenas, etc., se encuentran en un lugar central y todos saben dónde encontrarlas cuando se debe cambiar algo.
Esto es especialmente algo que parece gustarle a los gerentes de proyecto a medida que las personas van y vienen y de esta manera todos pueden cambiar cosas tan triviales sin tener que profundizar en la estructura de la aplicación.
Además, puede cambiar fácilmente el título de cuadros de grupo / páginas de pestañas similares, etc. a la vez. Otro aspecto es que puede imprimir esa clase y dársela a un no programador que puede verificar si los subtítulos son intuitivos, y si los mensajes al usuario son demasiado detallados o confusos, etc.
Sin embargo, veo ciertas desventajas:
- Cada clase está estrechamente unida a las clases constantes.
- Agregar / Eliminar / Renombrar / Mover una constante requiere la recompilación de al menos el 90% de la aplicación (Nota: Cambiar el valor no lo hace, al menos para C ++). En uno de nuestros proyectos C ++ con 1500 clases, esto significa alrededor de 7 minutos de tiempo de compilación (usando encabezados precompilados; sin ellos son alrededor de 50 minutos) más alrededor de 10 minutos de vinculación con ciertas bibliotecas estáticas.
- Crear una versión optimizada de velocidad a través del compilador de Visual Studio lleva hasta 3 horas. No sé si la gran cantidad de relaciones de clase es la fuente, pero también podría serlo.
- Te conducen a cadenas de codificación temporal temporalmente directamente en el código porque quieres probar algo muy rápido y no quieres esperar 15 minutos solo para esa prueba (y probablemente cada una de las siguientes). Todo el mundo sabe lo que sucede con los pensamientos de "Lo arreglaré más tarde".
- Reutilizar una clase en otro proyecto no siempre es tan fácil (principalmente debido a otros acoplamientos estrechos, pero el manejo de constantes no lo hace más fácil).
¿Dónde guardarías constantes así? Además, ¿qué argumentos presentaría para convencer a su gerente de proyecto de que existen mejores conceptos que también cumplen con las ventajas mencionadas anteriormente?
Siéntase libre de dar una respuesta específica o independiente de C ++.
PD: Sé que esta pregunta es un poco subjetiva, pero sinceramente, no conozco un lugar mejor que este sitio para este tipo de pregunta.
Actualización sobre este proyecto
Tengo noticias sobre el tiempo de compilación:
siguiendo las publicaciones de Caleb y gbjbaanb, dividí mi archivo de constantes en varios otros archivos cuando tuve tiempo. Finalmente, también dividí mi proyecto en varias bibliotecas, lo que ahora era mucho más fácil. Compilar esto en el modo de lanzamiento mostró que el archivo generado automáticamente que contiene las definiciones de la base de datos (tabla, nombres de columna y más, más de 8000 símbolos) y acumula ciertos hashes causó grandes tiempos de compilación en el modo de lanzamiento.
Desactivar el optimizador de MSVC para la biblioteca que contiene las constantes de DB ahora nos permitió reducir el tiempo total de compilación de su Proyecto (varias aplicaciones) en modo de lanzamiento de hasta 8 horas a menos de una hora!
Todavía tenemos que descubrir por qué MSVC tiene dificultades para optimizar estos archivos, pero por ahora este cambio alivia mucha presión, ya que ya no tenemos que depender solo de las versiones nocturnas.
Ese hecho, y otros beneficios, como un acoplamiento menos apretado, una mejor reutilización, etc., también mostraron que pasar tiempo dividiendo las "constantes" no era una mala idea después de todo ;-)
Actualización2
Dado que esta pregunta aún recibe algo de atención:
Esto es lo que he estado haciendo en los últimos años:
Ponga cada constante, variable, etc. exactamente en el ámbito que le resulte relevante: si usa una constante solo en un único método, está bien definirla en ese método. Si una sola clase está interesada en ella, déjela como un detalle de implementación privada de esa clase. Lo mismo se aplica para el espacio de nombres, módulo, proyecto, alcance de la empresa. También uso el mismo patrón para funciones auxiliares y similares. (Esto puede no aplicarse al 100% si desarrolla un marco público).
Hacer esto aumenta la reutilización, la capacidad de prueba y la capacidad de mantenimiento en un grado en el que no solo pasa menos tiempo compilando (al menos en C ++), sino también menos tiempo en la corrección de errores, lo que le deja más tiempo para desarrollar nuevas funciones. Al mismo tiempo, el desarrollo de estas funciones será más rápido, ya que puede reutilizar más código con mayor facilidad. Esto supera cualquier ventaja que pueda tener el archivo de constantes centrales por una magnitud.
Eche un vistazo especialmente al Principio de segregación de interfaz y al Principio de responsabilidad única si desea obtener más información.
Si está de acuerdo, vote la respuesta de Caleb ya que esta actualización es básicamente una versión más general de lo que dijo.