Buenas prácticas trabajando con parámetros o configuración del sistema



En éste artculo repasaremos algunas buenas prácticas sobre la utilización de parámetros para resolver temas como:
  • ¿Donde se utiliza cierto parámetro?
  • ¿Por qué tengo dos claves de parámetro para la misma configuración?
  • ¿Como resolver el valor por defecto del parámetro?
  • ¿Como almacenar parámetros?

Estructura y almacenamiento

Para el almacenamiento recomiendo una estructura atributo valor, la cual es elástica, por lo que no quedamos atados a una estructura en particular.

En este sentido, podríamos tener la estructura siguiente:

Parameters
* ParameterKey - VarChar(32)
* ParameterValue VarChar(512)

Para el caso de las claves (ParameterKey), es importante que sean descriptivas. Si fuesen numéricas, cada vez que ingresemos a revisar la base de datos, necesitamos la lista de mapeo para encontrar el parámetro deseado.
En lo que respecta a si la clave es case sensitive, se recomiendan lo más simple posible a fin de evitar errores en queries y otros. Por lo que se debiera establecer un solo case, ya sea mayúscula o minúscula.

Los tipos de datos utilizados dependerán del tipo de aplicación y cardinalidad de esta la tabla. Por lo que los expuestos funcionan a modo de ejemplo.

Métodos accesores y modificadores

Ya que tenemos definida la estructura, como buena práctica de desarrollo, es importante concentrar la lógica para la manipulación de la misma en un solo lugar.
Para ello, simplemente podremos definir dos procedimientos o métodos:
  • ParameterGet( in:ParameterKey, out:ParameterValue)
  • ParameterSet( in:ParameterKey, in:ParameterValue)
Como queda claro en el nombre de cada uno, ParameterGet retorna el valor de un parámetro y ParameterSet lo establece, realizando un upsert.

A su vez, conviene definir una serie de wrappers o envoltorios a fín de simplificar la utilización de parámetros, para no estar realizando conversiones innecesarias cada vez, ej.:
  • ParameterBoolGet( in:ParameterKey, out:BoolValue)
  • ParameterIntGet( in:ParameterKey, out:IntValue)
  • ParameterDecimalGet( in:ParameterKey, out:DecimalValue)
Ejemplo de "ParameterBoolGet":

&ParameterValue = ParameterGet( &ParameterKey)
&BoolValue.FromString( &ParameterValue)

Importante: No copiar la lógica de ParameterGet dentro de estos wrappers. De otra forma estaríamos duplicando código.

Encapsularlos en un procedimiento (gx) o función

Esto nos permite dos cosas:
  1. Tener una referencia de nuestros parámetros, lo que nos permite saber en donde están siendo utilizados.
  2. Un solo lugar encargado de la lógica del parámetro. Por ejemplo, su valor por defecto.

Para ejemplificar el caso, imaginemos estamos trabajando en un sistema el cual tiene un impuesto parametrizado. En ese caso, podríamos tener el siguiente proc o función:

Firma: ParameterTaxGet( out:&TaxValue)

&TaxValue = ParameterDecimalGet( Parameters.Tax)

// Se establece el valor por defecto
if &TaxValue.IsEmpty()
   &TaxValue = 22
   
   // Eventualmente, en algunos casos es necesario persistirlo en la DB
   ParameterSet(  Parameters.Tax, &TaxValue.ToString())
endif

Como se peude ver, la lógica queda encapsulada en un solo lugar y permite la manipulación completa del parámetro.

Ultimas consideraciones

Evitar escribir la clave del parámetro en el código

Al no escribir la clave-parámetro en el código, nos adelantamos a posibles errores de escritura y de referencias al parámetro.

Para esto, alcanza con definir un enumerado que contenga las claves de parámetros. Esto a su vez nos posibilita tener una idea clara de los parámetros utilizados en nuestro sistema.

Utilizar parámetros solo para la configuración del sistema

Se debe identificar si lo que queremos guardar como parámetro, es realmente un parámetro o si se trata de una salida facil para no crear las estructuras adecuadas.

Veamos el siguiente ejemplo del uso inadecuado de parámetros:

ParameterKey ParameterValue
CUSTOMER INVOICE MODE - 5 CREDIT
CUSTOMER INVOICE MODE - 6 DEBIT
CUSTOMER INVOICE MODE - 7 CREDIT

Aquí se puede ver que se establece un modo de factura para cada ID de cliente (5, 6, 7).

Como podemos visualizar, lo que se está reigistrando no es una configuraión del sistema, sino más bien una configuración a nivel de la entidad Customer. En este caso, convendría crear este atributo en dicha entidad.

Auditoría

Este punto dependerá de cada sistema, pero es importante dejar nota que se podrían disponer algunos atributos más, en la tabla de parámetros, en los cuales quede registrado fecha-hora y usuario que modificó el registro.

Comentarios

Entradas más populares de este blog

Buenas prácticas al registrar logs en desarrollo de software

Enviando nuestros logs a Kibana rápido y simple

Buenas prácticas al nombrar objetos en GeneXus