Implementar Formularios a través de Patrón Observer y Mediator.

Contexto

A través de extensiones ReactiveX se puede implementar de forma flexible formularios de datos que incluyan validaciones de formato en sus campos, dependencias entre estados de campos y presentación de mensajes de información.

Estas implementaciones a través de ReactiveX se basan en dos importantes patrones de diseño conocidos como Observer Pattern e Iterator Pattern (Design Patterns: Elements of Reusable Object-Oriented Software). Recordemos el diagrama de clases del patrón Observer.

Patrón Observer




La mayoría de los formularios cuentan con pocos campos para toma de registro de datos, sin embargo algunas soluciones involucran formularios extensos con múltiples campos, validaciones y dependencias.

¿Cuál es el mejor aprovechamiento para esos casos en donde se tiene muchas dependencias y relaciones entre múltiples campos?


En este artículo propongo el uso de una recomendación presentada en Design Patterns: Elements of Reusable Object-Oriented Software (página 300), la cuál consiste en recurrir al Patrón Mediator para gestionar las dependencias complejas que puedan existir entre Subjects y Observers, los elementos del Patrón Observer.

La implementación se hace para soluciones IOS usando como lenguaje Swift, sin embargo el concepto aplica para otros sistemas operativos y lenguajes OOP.

Componentes del formulario

En los formularios se van a encontrar los siguientes elementos:

Stream of characters: Es el flujo de datos compuesto por el texto que los usuarios ingresan en el campo. Puede ser representado por un Subject u Observable.

Function of validation: Es la función que valida el texto ingresado en el campo de texto, valida por ejemplo que el campo cumpla con cierto formato, tenga una máxima y mínima longitud preestablecida y cualquier otro tipo de verificación que sea requerida. Puede ser representado como un Observable.

Message of validation: Representa el mensaje informativo de advertencia que se muestra al usuario cuando el texto ingresado al campo no cumple con las validaciones definidas. Puede ser representado por un Observer.

SubmitButton: En este caso corresponde al botón principal de acción, en un formulario pueden existir varios botones de este tipo y además puede existir otros tipos de componentes de acción tales como checkbox, sliders, entre otros. Puede ser representado por un Observer.



Entre más campos y relaciones contenga el formulario más complejo se torna la implementación. Es justo en estos casos para los cuales se recomienda el siguiente aprovechamiento a través del Patrón Mediator.

Patron Mediator-Observer-Builder




ChangeManager: Representa el Mediator que gestiona las relaciones de dependencias entre Subjects/Observables y Observers.

ViewController: Controlador de la vista.

ViewModel: Elemento del Patrón MVVM. Expone el Stream de datos relevantes a la Vista.

Builder: Gestiona la creación del objeto tipo ChangeManager, contiene las operaciones de tipo buildParts del Patrón Builder (setSource, setValidationFunction, setObservers). Además realiza las asociaciones entre componentes y establece las relaciones (bind operations).

Observer: Representa los elementos observadores. En ReactiveX su estructura es la de un Iterator.

Observable: Representa el Subject del Patrón Observer y en ReactiveX es la fuente generadora de datos o información (streams).

Consideraciones de implementación


  • Esta propuesta aplica para formularios complejos en donde existen múltiples dependencias, para formularios sencillos probablemente no sea necesario.
  • La implementación se hace más sofisticada a través del uso del Patrón Builder para la creación del objeto ChangeManager, de esta forma es más clara la asignación de relaciones entre los múltiples campos.
  • El cliente del objeto ChangeManager es el ViewController, el cual a través de un builder crea una instancia de referencia.
  • ChangeManager no tiene referencia directa al ViewModel, conoce sus operaciones y propiedades sin mantener una referencia fuerte.

Evidencias



Repositorio


El código de ejemplo de aplicación se encuentra ubicado en mi repositorio.

Conclusiones


Con el ánimo de mantener un código limpio durante la implementación de formularios complejos se propone esta estrategia de aplicación de múltiples patrones. En situaciones en donde muchos elementos depende de muchos otros elementos esta estrategia podría ser adecuada. Si bien en este caso de aplicación se trataron únicamente formularios, la estrategia podría aplicarse a otros casos en donde gestionar las relaciones entre elementos de las API ReactiveX requiere ser flexible y limpia.




Thanks for your comment