http://www.tightlinecomputers.com/Documents/Des_Patterns.ZIP
Autor: Andy Kramek
Traducido por: Ana María Bisbé York
...continuación de (Patrones de diseño en Visual FoxPro (Parte 1/2))
¿Qué es un mediador y cómo lo utilizo?
El mediador describe una solución como una llave, que todos hemos encontrado siempre que tratamos de diseñar una clase nueva. Cómo tratar con situaciones donde un objeto tiene que responder a cambios, o controlar el comportamiento de otro.
¿Cómo reconozco donde necesito un mediador?
La definición formal del mediador, y dada por "GoF" es:
"Define un objeto que encapsula cómo interactúan un conjunto de objetos. El mediador estimula la pérdida de acoplamiento manteniendo objetos explícitamente, a partir de la referencias de otro, y le permite variar su interacción independientemente."
Este dirige uno de los problemas fundamentales que tenemos que afrontar en cualquier tarea de desarrollo de aplicaciones, que asegura que los objetos pueden comunicar con otros sin tener realmente que incluir referencias de código duro en sus clases.
En ningún lugar es esto más crítico, que al crear la interfaz de usuarios compleja que la generación actual usuarios finales de PC, no esperan; pero exigen. Típicamente, tenemos que hacer que toda la interfaz de usuario, responda como una única entidad, habilitando e inhabilitando funciones y controles como respuesta a las acciones del usuario u opciones, o, de acuerdo con sus derechos y permisos. Al mismo tiempo, queremos diseñar y generar clases genéricas, reutilizables. Los dos requerimientos están, aparentemente en conflicto directo uno con el otro.
Dele un vistazo al formulario de ejemplo el que hemos utilizado para ilustrar la cadena de responsabilidades en la sección precedente (Figura 6). Si ejecuta este ejemplo, verá que el botón de comandos "Add Tax" está activo cuando el formulario es instanciado, incluso si no existe la propiedad Price (precio). Por supuesto, al hacer clic en el botón con el precio de $0.00 simplemente retorna cero $0.00 y aparentemente no ocurre nada más. Pero, ¿qué pasa si se introduce un valor negativo? La respuesta corta es, que esto siempre puede ocurrir y funcionará, de tal forma, si introduce $ -29.95 como el precio y hace clic en el botón "Add Tax" el formulario le dirá que la tasa es $ -1.722 y el precio total es $ -31.67.
Podría ser mejor, si el botón "Add Tax" estuviese sólo habilitado cuando el precio fuera mayor que cero. Por supuesto, la solución más simple es justamente agregar una pareja de líneas de código al Valid() del cuadro de texto (textbox) de este formulario que implemente esta funcionalidad, como, por ejemplo:
IF This.Value > 0 ThisForm.cmdCalc.Enabled = .T. ELSE ThisForm.cmdCalc.Enabled = .F. ENDIF
Este tipo de "acoplamiento ligero" (Tight coupling) puede ser aceptable cuando estamos tratando con un cuadro de texto (textbox) y un botón de comandos en un único formulario. Sin embargo, rápidamente tendremos problemas si tratamos de adoptar esta solución al tratar con controles múltiples que tienen que interactuar en combinaciones diferentes y complejas. Incluso, encontrando dónde se especifica el código que controla una interacción particular, puede haber problemas, y simplemente cambiar el nombre de un objeto provoca daños mayores. Es aquí donde juega su papel el patrón de mediador.
La idea básica es, que cada objeto se comunica con un "mediador" central, el que conoce de todos los objetos que están al alcance actual, y cómo manipular su estado cuando un evento dado es reportado. De esta forma, evitamos todas las cosas asociadas con colocar código específico dentro de un método asociado con el evento Valid(). En su lugar, podemos escribir completamente código genérico con su clase padre. Entonces, si utilizamos un objeto mediador, podemos reemplazar el código específico en la instancia del cuadro de texto precio con el código algo así como lo siguiente:
This.oMediator.StateChange( This )
Como ha visto, el cuadro de texto no tiene idea de qué hará el mediador con la información, o incluso qué información desea. Todo lo que tiene que hacer es llamar al método "StateChange" y pasa una referencia por si misma. Cualquier acción subsiguiente es para especificar la implementación del mediador.