parameters - primer - tags para videos de youtube
¿Cómo manejar una gran cantidad de parámetros de configuración a través de un programa conceptualmente? (1)
Imagine un sistema de software en el que tenga como 100 parámetros, cada uno de los cuales es sensato para cambiar (en mi caso, este es un sistema de búsqueda para el aprendizaje automático). La solución obvia es almacenar todos los parámetros en un archivo de configuración, para que el sistema sea fácil de manejar y ver.
Su enfoque es mejor:
- a) cargar el archivo de configuración en el punto de entrada del programa y pasar una gran colección de variables de configuración a través de cada método en el código
- b) cargar el archivo de configuración en el punto de entrada del programa y pasar la colección relevante de variables de configuración a través de cada método en el código
- c) cargar las variables de configuración directamente donde se necesitan
- d) cargar la configuración y hacerla global
Estoy abierto a sugerencias o ejemplos de una implementación particular. En este momento estoy experimentando con variables de configuración anidadas, cada objeto anidado almacenando la configuración de diferentes módulos en el código.
Te recomiendo que hagas los siguientes pasos.
En primer lugar, use una sintaxis de archivo de configuración que admita el concepto de múltiples secciones / ámbitos y, preferiblemente, ámbitos anidables. Por ejemplo, un elemento XML es un ámbito anulable en el sentido del que estoy hablando, mientras que un archivo ".ini" proporciona secciones no insertables. Un archivo de propiedades de Java no proporciona soporte directo para ámbitos, pero puede emular dicho soporte utilizando la sintaxis xyz
para denotar la variable z
, en el alcance y
, que a su vez está anidada en el alcance x
. Config4 * (que desarrollé) proporciona soporte directo para ámbitos anidados.
Segundo, escriba el constructor de una clase Foo
configurable como se muestra en el siguiente pseudocódigo:
Foo(Configuration cfg, String scope) {
_x = cfg.lookup(scope + ".x");
_y = cfg.lookup(scope + ".y");
_z = cfg.lookup(scope + ".z");
_bar = new Bar(cfg, scope + ".bar");
}
En el pseudo código anterior, uso el _
prefijo para denotar una variable de instancia, y asumo que la clase de Configuration
tiene una operación de lookup()
que toma un nombre de ámbito, por ejemplo, cfg.lookup("foo.bar.abc")
devolverá el valor de la variable abc
en el alcance de foo.bar
.
En tercer lugar, la función main()
de su aplicación se puede escribir como se muestra en el siguiente pseudocódigo:
main(...) {
String configFileName = ...; // obtain from command-line argument
String scope = ...; // obtain from command-line argument
Configuration cfg = parseConfigurationFile(configFileName);
Foo foo = new Foo(cfg, scope + ".foo");
... // create other configured objects
doRealWork(foo, ...);
}
Finalmente, los argumentos de línea de comandos para su aplicación deben especificar: (1) el nombre de un archivo de configuración, y (2) un ámbito de nivel superior (dentro del archivo de configuración) que contiene variables de configuración para ejecutar la aplicación. Por ejemplo, supongamos que example.cfg
está estructurado de la siguiente manera:
instance1 {
foo {
x = "a value";
y = "another value";
z = "yet another value";
bar {
...
}
}
... # configuration for other objects
}
instance2 {
foo {
x = "...";
y = "...";
z = "...";
bar {
...
}
}
... # configuration for other objects
}
Puede ejecutar su aplicación como myApp.exe -cfg example.cfg -scope instance1
.
El consejo anterior proporciona los siguientes beneficios:
- Su aplicación puede crear múltiples objetos
Foo
, cada uno de los cuales se puede configurar de manera diferente, simplemente pasando un parámetro descope
diferente al constructor de cada objeto. - Los usuarios tienen la flexibilidad de poder almacenar múltiples conjuntos de variables de configuración dentro de un solo archivo de configuración, si así lo desean. Por ejemplo, un usuario puede tener diferentes conjuntos de variables de configuración para: (1) diferentes pruebas unitarias; (2) desarrollo, UAT y entornos de producción; (3) múltiples instancias de una aplicación de servidor replicada.
- Con el tiempo, puede escribir una biblioteca de clases configurables que siguen el principio de diseño anterior. Esa biblioteca de clases configurables puede reutilizarse en múltiples aplicaciones.
He utilizado el enfoque anterior en varias aplicaciones basadas en C ++ y Java Config4 * que escribí, y me ha funcionado bien. Si está utilizando un lenguaje que tiene soporte incorporado para la reflexión (como Java), entonces un enfoque alternativo es usar un marco de inyección de dependencia. Si no sabe qué es eso, realice una búsqueda en Internet de "inyección de dependencia", "inversión de control" o "Spring Framework".