Contenido lógico
Esta sección describe las mejores prácticas para construir la lógica interna de un proceso, incluyendo el uso de funciones, condicionales, bucles y matrices, lógica de navegación, invocaciones a transacciones y call APIs, y manipulación de objetos JSON. También incluye las mejores prácticas para el uso de la vista de código al construir un proceso.
Las funciones permiten encapsular la lógica en bloques reutilizables, lo que ayuda a simplificar procesos complejos y mejorar la legibilidad del código.
Las mejores prácticas a la hora de trabajar con funciones incluyen:
Asigna una sola responsabilidad a cada función: Cada función debe realizar una tarea única y bien definida. Si una función valida, formatea y calcula al mismo tiempo, es mejor dividirla en funciones más pequeñas.
Las funciones deben ser breves: Evita las funciones demasiado largas. No deben superar un número razonable de acciones.
Minimiza el acoplamiento estrecho: Siempre que sea posible, una función debe operar utilizando sus entradas y devolver un resultado, sin modificar directamente otras partes del proceso, a menos que ese sea su propósito explícito. Evita modificar variables fuera de su contexto a menos que sea absolutamente necesario.
Las estructuras condicionales permiten controlar el flujo de la aplicación basándose en condiciones evaluadas en tiempo de ejecución. Es esencial utilizarlas de forma clara y coherente para mejorar la legibilidad, evitar complejidades innecesarias y reducir el riesgo de errores lógicos.
Las mejores prácticas al utilizar condicionales incluyen:
Utiliza condiciones sencillas y expresivas: Evita las condiciones demasiado largas o con varios operadores lógicos anidados. Si una condición se vuelve compleja, considera la posibilidad de extraerla en una función con un nombre descriptivo.
Utiliza nombres de condiciones booleanas claros: Las variables o funciones utilizadas como condiciones deben explicarse por sí mismas. Por ejemplo: hasAvailableBalance en lugar de flag1.
Prioriza la legibilidad: Ordena las condiciones en función de la claridad o la probabilidad. En los condicionales de varias ramas (if/else if/else), coloca primero los casos más comunes o relevantes.
Evita el anidamiento profundo e innecesario: Demasiados condicionales anidados hacen que el flujo sea difícil de seguir. Considera la posibilidad de simplificar con funciones intermedias o bloques separados.
Nota
Como los procesos lambda no admiten actualmente retornos anticipados, puedes utilizar sentencias "else if" anidadas como alternativa.
Consolida condiciones similares: Si varias ramas comparten una lógica similar, considera la posibilidad de agruparlas para evitar duplicaciones.
Trata todos los casos posibles: Asegúrate de que todos los escenarios previstos están cubiertos con otros bloques o validaciones adicionales. Esto es especialmente importante para evitar resultados inesperados o flujos incompletos.
Evita la lógica de interfaz de usuario en condicionales de negocio: Separa la lógica que impulsa las decisiones de negocio de la lógica que afecta a la interfaz (por ejemplo, mostrar u ocultar componentes, aplicar estilos).
Documenta las reglas complejas con nombres claros o comentarios mínimos: Cuando una condición combine inevitablemente varias reglas de negocio, incluye una breve explicación. Si es posible, encapsúlela en una función con un nombre claro.
Esta sección describe las mejores prácticas para trabajar con estructuras de datos repetitivas, como listas y matrices, y para construir lógica iterativa utilizando bloques de tipo bucle. Permiten recorrer, filtrar y transformar listas de forma clara y eficaz.
Las mejores prácticas al utilizar bucles incluyen:
Utiliza el bloque for (index) from (0) to (0) do cuando el número de iteraciones sea conocido y necesites acceder al índice de iteración (por ejemplo, procesando por posición o accediendo a múltiples arrays en paralelo).
Utiliza el bloque for element cuando iteres sobre una lista sin necesidad del índice, ideal para operaciones como el filtrado o la asignación en las que se trabaja directamente con cada elemento (consulta la plantilla de filtrado).
Utiliza el bloque while do cuando la condición del bucle sea dinámica y no se base en un número fijo de iteraciones.
Las mejores prácticas para las operaciones que utilizan matrices incluyen:
Obtener la longitud del array: Utiliza el bloque length of array [] para obtener la longitud de una matriz. Este es el método estándar para determinar el tamaño de una matriz.
Search (find first): No hay ningún bloque incorporado para esto, por lo que s implementarlo manualmente. Como necesitas el índice para esta operación, utiliza el bloque for (index) from (0) to (0) para obtenerlo.
Filtrar: Del mismo modo, el filtrado debe construirse manualmente mediante un bucle. Dado que el filtrado consiste en recuperar filas completas en lugar de índices específicos, utiliza para ello el bloque for element.
Obtener el valor de la celda: Para recuperar el valor de una celda, utiliza el bloque array table value. La expresión #A no debe utilizarse.
La navegación y la interacción con la interfaz de usuario se definen a través de los bloques Next.
A excepción del bloque execute inline lambda, los bloques Next no se ejecutan en el momento en que se declaran. En su lugar, se ponen en cola y se activan al final del proceso. En otras palabras, no pausan ni interrumpen el flujo; se recogen durante la ejecución y sólo se ejecutan una vez finalizado el proceso.
Las mejores prácticas al utilizar los bloques Next incluyen:
Evita utilizar el bloque "command", salvo en los casos en que no exista un bloque específico (por ejemplo, invocación de módulos de flujo funcional o ventanas emergentes del sistema).
Evita utilizar variables o registros como valores en los bloques Next. Esto limita la capacidad de rastrear el uso de la funcionalidad Used in. En los casos en que esto sea inevitable (por ejemplo, cuando la lógica pueda invocarse desde múltiples fuentes y deba volver al origen), documenta claramente el motivo.
Declara el bloque Next en el momento lógico en que se requiere la navegación, aunque su ejecución se producirá al final. Esto elimina la necesidad de variables temporales utilizadas únicamente para gestionar la navegación posterior.
En los bloques de grupo o de componente, los eventos disponibles son genéricos. Sin embargo, es posible añadir otros eventos permitidos para el tipo, aunque no aparezcan por defecto.
Como se menciona en la sección Estructura del modelo, se recomienda encapsular la invocación de la transacción dentro de una función específica que también incluya el manejo de errores. Esto ayuda a estandarizar la implementación y simplifica el mantenimiento.
Importante
Aún se están desarrollando las mejores prácticas para la gestión de errores en las transacciones.
Las mejores prácticas a la hora de invocar transacciones incluyen:
Al nombrar la función que invoca la transacción, utiliza el prefijo invokeTrx + código o un nombre descriptivo (por ejemplo, invokeTrx2054 o invokeTrxGetAccounts).
Asigna el contrato de transacción (bloque) a una variable. Define una variable denominada trx + código o un nombre representativo (por ejemplo, trx2054 o trxGetAccounts).
Coloca el tratamiento de errores entre la asignación del contrato de transacción y la ejecución. Esto permite validar condiciones específicas para cada transacción.
Utiliza el bloque execute transaction para invocar la transacción.
Evita asignaciones de entrada redundantes. Si el registro de entrada es el mismo que el registro que contiene el valor a enviar, deja el valor como " ". En este caso, se utilizará automáticamente el valor de registro correspondiente.
Comprueba que la transacción existe en la rama vinculada a la aplicación o módulo. Esto es crucial cuando se importan procesos de otro ambiente o después de realizar un merge o cambios de dependencia.
Los procesos lambda permiten definir la ejecución de una transacción como asíncrona, lo que puede resultar útil en situaciones en las que no es necesario esperar una respuesta o cuando se desea mejorar el rendimiento de la aplicación. La ejecución asíncrona de transacciones debe utilizarse cuando la respuesta de la transacción no es relevante para el flujo inmediato del usuario, y en procesos de registro, seguimiento, notificación o auditoría que no deben bloquear la interacción del usuario.
Importante
La ejecución de transacciones asíncronas no está disponible en Webfly.
Algunas consideraciones importantes cuando se utilizan ejecuciones de transacciones asíncronas incluyen:
No aplicar lógica que dependa del resultado inmediato.
Evitar continuar con una lógica que asuma que la transacción ya ha devuelto un resultado.
Incluir lógica de posprocesamiento si es necesario. Si hay que tomar alguna medida en función del resultado, crear un proceso independiente para gestionarlo.
Evitar el uso de transacciones asíncronas para validaciones críticas. En los procesos en los que la transacción determina si se procede o no (por ejemplo, inicio de sesión, validación de límites), utilizar siempre la ejecución síncrona.
Utilizar el prefijo trxAsync al nombrar la variable.
Evitar la invocación simultánea de transacciones. Independientemente del tipo de invocación (sync o async), las transacciones se ponen en cola en el dispositivo, lo que significa que sólo se ejecuta una a la vez.
Importante
En las aplicaciones iOS, si se invocan varias transacciones asíncronas, sólo se ejecuta la última acción siguiente.
Las call APIs permiten interactuar con servicios de terceros o funciones nativas del dispositivo (por ejemplo, cámara, lector biométrico o notificaciones).
Importante
Aún se están desarrollando las mejores prácticas para la gestión de errores en las call APIs.
Las call APIs utilizan un rango predefinido de registros para los datos de entrada y salida:
Registros de entrada: 390 a 399
Registros de salida: 290 a 299
Actualmente hay tres bloques disponibles para invocar una call API:
execute call api
execute call api ( ) and response code
execute call api < > and response success
Al igual que con las transacciones, se recomienda encapsular la invocación a la call API dentro de una función dedicada que también gestione los errores. Esto estandariza la implementación y simplifica el mantenimiento.
Las mejores prácticas a la hora de invocar call APIs incluyen:
Al nombrar la función que ejecuta la call API, utilizar el prefijo invokeCallAPI + código o un nombre descriptivo que represente la call API.
Asignar la call API a una variable. Definir una variable llamada callAPI + código o un nombre representativo.
Utilizar el bloque execute call api para invocar la call API.
Importante
A diferencia de las transacciones, la gestión de errores en las call APIs no interrumpe la ejecución del proceso después del bloque de ejecución.
Devolver el valor del registro 112 (resultado de la call API) como salida de la función. La función puede llamarse directamente desde una estructura condicional (por ejemplo, if), evaluando el resultado devuelto.
Asegurarse de que la call API está configurada en Studio. La especificación de las call APIs debe definirse en el archivo de configuración correspondiente. Esto es especialmente importante cuando se importan procesos de otro ambiente.
Comprobar que el SDK correspondiente está activado en Mobile Builder para el binario que se está utilizando. Si no está activado, la call API no funcionará y la aplicación podría fallar.
Los procesos lambda permiten la manipulación de objetos JSON, esto incluye la creación y el análisis del JSON.
Las mejores prácticas al manipular objetos JSON incluyen:
Evitar crear manualmente el JSON como texto plano.
Utilizar nombres de clave coherentes y descriptivos. Evitar claves ambiguas o genéricas como valor1, param o datos.
Documentar las estructuras previstas. Proporcionar documentación o un ejemplo de la estructura JSON esperada en un comentario para mejorar la claridad y la capacidad de mantenimiento.
El editor de procesos lambda permite construir la lógica a través de una herramienta de programación visual que se utiliza para construir un proceso arrastrando y soltando bloques con forma de piezas de rompecabezas en un lienzo y disponiéndolos según sea necesario. Sin embargo, también ofrece una segunda vista llamada Code, que muestra una representación TypeScript de la lógica creada.
Es importante señalar que esta vista no representa la fuente original de la lógica, sino una traducción generada automáticamente a partir de los bloques configurados. Por ello, es importante tener en cuenta los siguientes aspectos a la hora de utilizarlo:
Los cambios realizados en la vista Code no se guardan como parte del proceso.
Cada vez que se pasa de la vista Block a la vista Code, se genera una nueva representación desde cero.
Si modificas manualmente el código, el sistema intentará asignarlo de nuevo a bloques al volver a la vista Blocks, pero esta asignación puede fallar si se han introducido estructuras no compatibles.
Algunos cambios pueden reorganizar la lista de sentencias (como el bloque contenedor on start y los bloques de función) al volver a la vista Blocks.
Las mejores prácticas al utilizar la vista Code incluyen:
Utilizar la vista Code como apoyo para revisar o leer la lógica, especialmente cuando se necesita una visión más lineal del proceso.
Aprovechar la opción de buscar y reemplazar de esta vista para encontrar rápidamente referencias a contenidos específicos, como variables.
Utilizar esta vista para comparar estructuras complejas (como bucles o validaciones anidadas) que pueden ser más difíciles de seguir en la vista Block.
Copiar y pegar estructuras lógicas cuando sea útil.
Al utilizar la vista Code también es importante evitar lo siguiente:
Utilizar código que no puede representarse en bloques (por ejemplo, operadores avanzados, llamadas a funciones no admitidas, etc.).
Confiar en que se conservará el código editado. Los cambios, como las definiciones de variables, pueden alterarse al volver a la vista Blocks.