Notas de estudio del marco PureMVC

Solía ​​​​usar un marco de interfaz de usuario simple para la capa de interfaz de usuario de mis propios proyectos. Descubrí que la escalabilidad no era sólida y la colaboración de varias personas en proyectos grandes también era un problema, así que aprendí el PureMVC más clásico basado en MVC y el Marco Loxodon basado en MVVM. Hoy registraré información sobre el estudio PureMVC.

pensamiento MVC

¿Qué es MVC?

El nombre completo de MVC es Model View Controller, que es la abreviatura de model-view-controller, es un modelo de diseño de software. Utiliza un método para separar la lógica empresarial, los datos y la visualización de la interfaz para organizar el código y reunir numerosas lógicas empresariales en un solo componente. Si bien la interfaz y la interacción del usuario deben mejorarse y personalizarse, no es necesario reescribir la lógica empresarial. reducir el tiempo de codificación.

MVC comenzó a existir en los programas de escritorio: M se refiere al modelo de negocio, V se refiere a la interfaz de usuario y C se refiere al controlador.

El propósito de usar MVC es separar los códigos de implementación de M y V, de modo que el mismo programa pueda usar diferentes formas de expresión. Las capas Modelo y Vista se desacoplan a través del Controlador. De manera similar, MVVM y MVP también desacoplan las capas Modelo y Vista a través de VM y P. La ventaja de adoptar esta idea es que reduce el acoplamiento entre M y V, facilita la expansión, la reutilización y la gestión.

clip_image006

Figura: diagrama de estructura MVC (línea continua -> representa dependencias; línea discontinua -> representa eventos, notificaciones, etc.)

Las ideas centrales de MVC son: reutilización del código y separación de preocupaciones.

Modelo: el modelo de datos se utiliza para encapsular datos relacionados con la lógica empresarial de la aplicación y cómo procesar los datos. El modelo tiene acceso directo a los datos, como el acceso a una base de datos. ""Modelo"" no depende de "VISTA" ni de "Controlador". Los datos en el modelo generalmente se publican a través de un mecanismo de actualización. Para implementar este mecanismo, aquellas Vistas que necesitan monitorear este Modelo primero deben registrarse en este Modelo: Lograr monitorear cambios en el modelo de datos. (Patrón de observador "publicar y suscribirse")

Ver (Ver): la capa de vista puede realizar la visualización intencionada de datos (función opcional). Generalmente no hay lógica de programa en Ver (puede tener una interfaz de visualización simple). Para implementar la función de actualización en la Vista, la Vista necesita acceder al modelo de datos que monitorea, por lo que primero debe registrarse con los datos monitoreados por la Vista.

Controlador: El controlador desempeña un papel organizativo en diferentes niveles y se utiliza para controlar el flujo de la aplicación. Maneja eventos y responde. Los "eventos" incluyen el comportamiento del usuario y cambios en el modelo de datos.

Marco de interfaz de usuario simple

1. Métodos centrales del marco de la interfaz de usuario

  • BaseUI registrará el nombre de la UI y el Controlador se utiliza para desacoplar la UI de métodos de operación específicos.
  • UIManager utiliza un diccionario para registrar todos los componentes de la interfaz de usuario y luego proporciona algunos métodos para abrir y cerrar la interfaz de usuario.
  • EventManager (sistema de mensajes) realiza la interacción entre diferentes módulos. El sistema de mensajes generalmente usa el modo de observador para registrar (suscribir) múltiples métodos con una palabra clave y luego usa esta palabra clave para notificar los métodos registrados.

2. Método de expansión del marco de la interfaz de usuario

  • ResourceManager (administrador de recursos) encapsula algunos métodos de carga de recursos, como carga sincrónica, carga asincrónica, carga y creación de instancias, etc.
  • DataHelper (analizador de datos) encapsula aún más los complementos de serialización y deserialización para XML, Json, Protobuf y otros formatos de datos.
  • Patrón singleton singleton
  • Common Extension (componente de extensión pública) utiliza genéricos y métodos de extensión para encapsular aún más los métodos en Unity para acelerar el desarrollo.

3. Ventajas y desventajas de un marco de interfaz de usuario simple

  • Fácil de usar
  • Relativamente fácil de entender para principiantes en C#
  • Sólo apto para proyectos muy pequeños.
  • Escalabilidad muy pobre
  • La lógica se acumulará bajo el script MonoBehaviour, lo que reducirá la eficiencia.

Después de analizar las trampas del marco de interfaz de usuario simple anterior, me di cuenta de que un proyecto más grande, o un proyecto colaborativo y abierto con varias personas, debe tener un marco más confiable como base. Hay varios marcos comunes en Unity, que son También una extensión del marco clásico. Como PureMVC, LoxodonFramework, etc.

Marco puroMVC

Ventajas y desventajas de PureMVC:

  1. Utilice intermediarios, agentes y patrones de comando para lograr el desacoplamiento, y utilice el acoplamiento directo de Modelo, Vista y Controlador para reducirlo más a fondo y mejorar la reutilización de algunos códigos.
  2. Tanto la interfaz de visualización como los datos del modelo se pueden reutilizar
  3. El código es demasiado redundante. Para funciones simples, es necesario crear los scripts de Vista, Mediador, Comando, Fachada, Proxy, Modelo y otros correspondientes.
  4. El proceso de operación es relativamente engorroso y el código en Mediator parece complicado y difícil de entender.
  5. Los mensajes requieren más rendimiento en forma de reflexión (la nueva versión ya utiliza delegación)

Características de PureMVC:

  1. La entrega de notificaciones requiere operaciones de boxing y unboxing (la nueva versión ha adoptado delegación genérica)
  2. Los comandos/notificaciones se implementan en el modo observador, utilizando la reflexión para obtener métodos y ejecutarlos (la nueva versión ha sido modificada para delegar)
  3. No hay ningún módulo de servicio que deba agregar usted mismo
  4. Y los datos se pasan a través de notificaciones. SendNotification tiene solo un parámetro de tipo de objeto. Sentirá que la transmisión de datos es lo primero. Los datos se pueden combinar en una clase para pasar, y solo es necesario restringir la clase.

PureMVC Core Scripts //Archivos principales

1.View.cs: IView.cs

  1. El diccionario mediatorMap registra los mediadores registrados (la clave es el nombre del mediador, el valor es la interfaz del mediador)
  2. El diccionario observerMap registra los observadores registrados (la clave es el nombre del evento, el valor es la interfaz del observador)
  3. Proporcionar métodos para registrar/anular el registro de mediadores y observadores (Registrar, Eliminar)
  4. El método principal notifica al método observador NotifyObervers
  5. Implementar vista singleton

La interfaz IView.cs especifica los métodos que implementará View
2.Controller.cs: IController.cs

  1. El diccionario CommandMap registra los comandos registrados (la clave es el nombre del comando, el valor es Func<ICommand>)
  2. Registre la interfaz IView para ejecutar notificaciones en la Ver. A IView se le asigna un valor al construir el Controlador.
  3. Controlador de implemento singleton
  4. Proporciona interfaces para registro, cancelación y ejecución de comandos (Registrar, Eliminar, Ejecutar)
  5. La interfaz IController.cs especifica los métodos que implementará View

3.Model.cs: IModel.cs

  1. El diccionario proxyMap registra el modelo proxy (Proxy) registrado (la clave es el nombre del proxy, el valor es la interfaz del tipo de proxy)
  2. Métodos para implementar IModel, incluidos los métodos de registro, cancelación y adquisición de poderes.
  3. Implementar modelo singleton
  4. La interfaz IModel.cs especifica los métodos que implementará Model

GameObject: Básicamente la capa más baja (vista UI), no depende de ninguna clase PureMVC excepto los propios componentes de Unity.

Mediador: solo se basa en GameObject y está vinculado uno a uno con GameObject. La entrada de GameObject se pasa a la llamada del Mediador a través de eventos .

Comando: la capa más baja se comunica con el Mediador a través del sistema de mensajes y depende del Proxy (porque a veces es necesario obtener entidades a través del Proxy para realizar algunas operaciones, y el Proxy solo realiza algunas operaciones de datos).

Proxy: La capa más baja, no depende de ninguna clase excepto de la clase de datos correspondiente.

Ver: Singleton, además de incorporar un sistema de mensajes en modo observador, su responsabilidad es solo administrar el Mediador (Registrar, Eliminar, Recuperar, Tiene)

Controlador: Singleton, que llama internamente al método de escucha del sistema de mensajes, su responsabilidad es únicamente gestionar Comando (Registrar, Eliminar, Ejecutar, Tiene)

Modelo: Singleton, responsable únicamente de gestionar Proxy (Registrar, Eliminar, Recuperar, Tiene)

Fachada: Singleton, responsable de administrar Vista, Controlador y Modelo, debido a que Vista tiene un sistema de mensajes, también tiene la función de enviar mensajes indirectamente.

Notificador: clase funcional, que llama al sistema de mensajes de Facade para notificar a otros objetos, por lo que esencialmente llama al sistema de mensajes de View (Observador) para enviar mensajes.

De las funciones de estas clases se puede ver que cada clase tiene una única responsabilidad y las funciones están claramente separadas. El controlador utiliza el tipo correspondiente para crear objetos para llamar a métodos y crea una instancia de una clase cada vez que se ejecuta un comando. El sistema de mensajes de Observer utiliza el nombre del método del objeto de reflexión (GetMethod) para llamar al método del objeto de observación. La nueva versión ha utilizado delegación genérica para resolver este problema.

                                Figura: Diagrama de diseño de PureMVC (tomado del sitio web oficial )

Se puede ver claramente en el dibujo de diseño que, además de la capa central Fachada, también hay Mediador, Proxy y Comando.

El objetivo del marco PureMVC es muy claro: divide el programa en tres capas de bajo acoplamiento: Modelo, Vista y Controlador. Es gestionado uniformemente por Facade.

  1. El modelo guarda una referencia al objeto Proxy. Proxy es responsable de operar el modelo de datos y comunicarse con servicios remotos para acceder a los datos.
  2. La vista contiene una referencia al objeto Mediador. El componente de vista específico "ViewComponent" es operado por el objeto Mediador
  3. El controlador guarda el mapeo de todos los comandos. El comando puede obtener el objeto Proxy e interactuar con él, y ejecutar otros comandos enviando una notificación. (La esencia sigue siendo el sistema de observación dentro de View)
  4. El proxy es responsable de operar el modelo de datos ¿Qué es un modelo de datos? El modelo de datos es base de datos, XML, etc. Podemos entender intuitivamente que Proxy es una clase utilizada para consultar, insertar, actualizar, eliminar y otras operaciones en el modelo de datos. Una vez completada la operación, se enviará un mensaje de notificación para notificar a otras capas que se actualicen. El proxy solo envía información y no monitorea información para evitar el acoplamiento.
  5. El mediador es responsable de operar componentes de vista específicos, que incluyen: agregar detectores de eventos, enviar o aceptar notificaciones y cambiar directamente el estado de los componentes de vista. Por ejemplo: agregue un evento al Botón, envíe una Notificación cuando se haga clic en el Botón y dígale al Controlador que realice la operación correspondiente. Por ejemplo, para un botón de inicio de sesión, el Mediador enviará una notificación al controlador y le indicará que realice la operación de inicio de sesión. El mediador también es responsable de cambiar directamente el estado de la vista. Por ejemplo, después de hacer clic en el botón de inicio de sesión, Mediator cambia el botón de inicio de sesión a gris para evitar operaciones repetidas. También es posible mostrar un mensaje en la vista que me indique que se está realizando una operación de inicio de sesión, etc. Resumen Medoator se utiliza para gestionar vistas específicas.
  6. El comando puede obtener el objeto Proxy e interactuar con él, y ejecutar otros comandos enviando una notificación. Por ejemplo, después de hacer clic en el botón de inicio de sesión, el Mediador le indicará al Controlador que ejecute el Comando correspondiente. Dado que iniciar sesión requiere conocer la información del usuario, el Comando le indicará al Proxy que consulte la base de datos u otros modelos de datos para acceder a los datos correspondientes. Después de que el Proxy consulta los datos, envía una Notificación para notificar al Comando que la consulta se ha completado y luego devuelve la información al Comando para su verificación. Al mismo tiempo, el Mediador también puede recibir la Notificación enviada por el Proxy y decirle al usuario que la información se está verificando a través de la vista. Después de que Command verifica la información del usuario, envía una Notificación para devolver el resultado de la verificación al Mediador e informa al usuario sobre el resultado de la verificación. O el Comando también puede enviar Notificación para realizar otras operaciones del Comando, como verificar la lectura de los detalles de la información del usuario, etc.

Patrón de diseño PureMVC

Patrón de proxy: proporciona un proxy para que otros objetos controlen el acceso a este objeto.

Uso: El modo proxy en PureMVC aísla la interacción directa entre los datos y otros sistemas y opera a través de la clase proxy de los datos. Debido a que la clase proxy hereda del Notificador, el Proxy también puede acceder a la Vista a través de Notifier.facade y el Controlador. lo que aísla efectivamente el acoplamiento entre clases de datos y otras clases, mejorando la reutilización de las clases de datos. Los datos de dichas clases de datos se pueden generar mediante herramientas de planificación, lo que hace que el desarrollo sea más conveniente.

Modo de apariencia: proporciona una interfaz consistente para un conjunto de interfaces de un subsistema. Este modo define una interfaz de alto nivel para hacer que el subsistema sea más fácil de usar, incorporando perfectamente la inversión de dependencia y la ley de Demeter. El uso del patrón de apariencia puede reducir las dependencias entre subsistemas. Puede configurar una clase Facade para el subsistema anterior y luego usar la clase Facade para interactuar con el nuevo sistema, reduciendo la dependencia del sistema anterior del sistema de información y creando relaciones complejas.

Uso: La clase Facade escrita usando el modo de apariencia en PureMVC es la interfaz externa principal de todo el marco MVC. Vista, Modelo, Controlador se registran en la clase Facade y se implementan singletons. Tiene casi todas las interfaces externas en la clase principal de MVC. Es una interfaz típica de alto nivel.

Patrón de observador: es una relación de dependencia de uno a muchos que permite que varios objetos observadores monitoreen un objeto temático al mismo tiempo. Cuando el objeto temático cambia, se notificará a todos los objetos observadores para que puedan actualizarse automáticamente.

Uso: en el marco PureMVC, use el modo observador y registre el evento de UI correspondiente para el mediador en el constructor de la clase de mediador. Cuando la UI activa el evento, el mediador enviará la notificación al observador a través de la Vista. Ver Registre el diccionario de observadores correspondiente a cada evento, recorra los observadores y luego ejecute los eventos específicos en la notificación. Los eventos de notificación se agregan anulando el método ListNotificationInterests al construir el mediador. La implementación del modo de comando en PureMVC también envía notificaciones y permite a los observadores ejecutar comandos activados llamando a ExcuteCommand en el Controlador.

 Patrón mediador: utilice un objeto mediador para encapsular una serie de interacciones de objetos. Los mediadores eliminan la necesidad de referencias explícitas entre objetos, haciéndolos débilmente acoplados y permitiéndoles cambiar de forma independiente las interacciones entre ellos.

Las ventajas y desventajas de los mediadores son obvias: algo reduce el acoplamiento entre clases concretas, lo que permite cambiar y reutilizar cada tipo de forma independiente. La desventaja es que el control del intermediario se volverá más complicado con la complejidad de la lógica, lo que hará que el intermediario asuma demasiadas tareas.

Uso: el patrón intermediario se utiliza en el marco PureMVC para aislar eficazmente el acoplamiento entre la capa de Vista y las capas de Controlador y Modelo. La Vista puede realizar operaciones y procesamiento de datos de manera efectiva a través del proxy de datos que contiene.

Modo de comando: encapsule una solicitud como un objeto (es decir, el objeto Comando que creamos), de modo que los clientes puedan parametrizarse con diferentes solicitudes; poner en cola solicitudes o registrar registros de solicitudes y admitir operaciones revocables.

Comando abstracto Comando: define la interfaz del comando y declara el método de ejecución.

Comando concreto ConcreteCommand: El comando específico implementa el método a ejecutar, suele ser una implementación virtual y suele tener un receptor (Receiver), el objeto que realmente ejecuta el comando. Cualquier clase puede convertirse en destinatario, siempre que pueda implementar las funciones correspondientes requeridas por el comando.

Invocador: solicita al objeto de comando que ejecute la solicitud. Por lo general, contiene el objeto de comando y puede contener muchos objetos de comando. Aquí es donde el cliente realmente activa el comando y requiere que el comando realice la operación correspondiente, lo que equivale a ingresar al objeto de comando.

Cliente Cliente: el comando lo crea el cliente y se establece el destinatario del comando.

Uso: SimpleCommand y marcoCommand heredan la interfaz ICommand e implementan el método Execute. Llame a SendNotifacation en el código, y luego la notificación será notificada al observador en el método View.NotifyObserver(). El observador ejecuta el ExecuteCommand en el Controlador. El ExecuteCommand obtendrá la interfaz de comando del diccionario, llamará a Execute para ejecutar el Comando reescrito y realice la solución.

Patrón singleton: el patrón singleton es el patrón de diseño más utilizado. Como sugiere el nombre, una clase tiene solo una instancia.

El modo singleton proporciona un punto de acceso global, lo que hace que el desarrollo de programas sea más flexible, pero el aumento de clases singleton también provocará un acoplamiento excesivo del código, lo que reducirá la reutilización y el mantenimiento.

Uso: en PureMVC, Facade, View, Model y Controller implementan el modo singleton, lo que hace que el acceso por lotes sea más conveniente y agregan la palabra clave volátil (volatile se usa principalmente en entornos de subprocesos múltiples. Cuando una variable se define como volátil, al leer el valor de esta variable, se lee desde la memoria cada vez en lugar de leer desde el caché. Esto se hace para garantizar que la información leída de la variable esté actualizada, independientemente de cómo otros subprocesos actualicen esta variable), proporcionando mutua La interfaz de llamada.
 

Patrón de diseño de fachada: durante el proceso de desarrollo, necesito obtener los objetos Vista y Modelo en el Controlador, modificar el Modelo, actualizar la Vista u obtener el Modelo en la Vista y realizar operaciones de inicialización. En el caso de muchos negocios lógica, Modelo, Habrá muchas llamadas frecuentes entre Vista y Controlador, y se mejorará el acoplamiento. En PureMVC, una interfaz de capa superior es responsable de la administración y operación de todas las capas centrales (Modelo, Vista, Controlador) En PureMVC, utilice el patrón de diseño Fachada desarrollado.

Definición del patrón de diseño de apariencia: "Proporcionar una interfaz unificada para un grupo de subsistemas o interfaces para simplificar su complejidad y reducir el acoplamiento".

La clase Facade debe tratarse como una clase abstracta y nunca crearse una instancia directamente. Debe escribir específicamente una subclase de Facade y agregar o anular métodos de Facade para implementar aplicaciones específicas. Esta clase se llama "ApplicationFacade" (póngale el nombre que desee, por supuesto).

Como se mencionó anteriormente, es el principal responsable de acceder y notificar al Modelo, Vista y Controlador. Eso es gestionar estos tres.

Facade es el "intermediario" de Modelo, Vista y Controlador. Al escribir código, no es necesario importar los archivos de clase de estos tres ni utilizarlos directamente. La clase Facade ya contiene la construcción de los tres singletons MVC principales en el método de construcción.

La clase Facade inicializa los objetos Modelo, Vista y Controlador en el constructor y guarda referencias a ellos en variables miembro.

De esta forma, Facade puede acceder al Modelo, Vista y Controlador. De esta manera, todas las operaciones en la capa central se concentran en Fachada, lo que evita que los desarrolladores operen directamente la capa central.

Inicializar fachada

Generalmente, las aplicaciones reales tienen una subclase de fachada. Este objeto de clase de fachada es responsable de inicializar Proxy, Mediator y Command, establecer el mapeo entre los nombres de Command y Notification, o registrar todos los Proxy y Mediator mediante la ejecución de un Command.

En este momento se mencionó Comando, Proxy y Mediador, su relación correspondiente es en realidad:

Proxy=>Modelo

Mediador=>Ver

Comando=>Controlador

¿Qué son el modelo y el proxy?

En la captura de pantalla anterior, puede ver el diagrama de relación entre Modelo y Proxy.

El modelo son datos (Objeto de datos) y el juego se basa en datos. Por ejemplo, los datos de los personajes, incluidos HP, MP, monedas de oro, niveles, habilidades, etc., se administran a través de Proxy en PureMVC. Proxy es el patrón de diseño de proxy, que "proporciona un proxy para que otros objetos controlen el acceso a ese objeto". Proxy se utiliza para controlar y administrar el modelo de datos en PureMVC.

"Objeto de datos" es un objeto que almacena datos en una estructura arbitraria. En otras palabras, no nos comunicaremos directamente con el Modelo. Todas las adiciones, eliminaciones, modificaciones y consultas al Modelo se manejan a través de Proxy.

En cuanto al modelo de agencia Proxy, por ejemplo, el agente Proxy de la estrella Cristiano Ronaldo es el equipo de Cristiano Ronaldo. Todos los asuntos de cooperación empresarial se manejan a través del equipo de Cristiano Ronaldo. De esta manera, Cristiano Ronaldo no necesita afrontar el costo de la cooperación. y comunicación solo desde todas las direcciones (Reducir el acoplamiento), al mismo tiempo, el equipo también puede ayudar a Cristiano Ronaldo a manejar muchos asuntos, sin la necesidad de que todo pase por Cristiano Ronaldo (ocultando sus detalles de implementación interna hasta cierto punto), desde Desde la perspectiva del código, también es satisfactorio "Cambiar uno no afecta a los demás". Mis modificaciones a algunos datos no deberían afectar a otros datos.
Sigamos mirando el diagrama de arriba y observemos la flecha del Modelo, solo interactúa con la Fachada. Como se mencionó anteriormente, esto es para reducir el acoplamiento.

Los Objs al lado son Modelos, que corresponden a Proxy, pero un Modelo no corresponde a un Proxy. Si es así, sería demasiado engorroso. Por ejemplo, un módulo puede incluir muchos datos de Modelo diferentes y usted puede definir múltiples datos diferentes. Modelo, pero se puede gestionar a través de un Proxy, lo cual es más conveniente. 

Los datos del modelo generalmente se obtienen o configuran de forma sincrónica. Proxy puede proporcionar una API para acceder a algunas propiedades o métodos de DataObject, o puede proporcionar directamente una referencia a DataObject (pero esto no se recomienda, debemos proteger el modelo y proporcionar las interfaces de acceso correspondientes). Si se proporciona un método para actualizar el objeto de datos, se enviará una notificación para notificar a otras partes del sistema cuando se modifiquen los datos.

La notificación de notificación aquí es en realidad el modo de observador. Cuando un objeto cambia, muchos otros objetos también necesitan responder a él. En este momento, se utiliza el modo de observador, el modo de publicación-suscripción, como Nos suscribimos a un determinado público de WeChat. cuenta, y la cuenta pública publica un artículo, y todos los usuarios suscritos pueden recibir recordatorios. Esto está en todas partes del juego. Cuando el modelo cambia, se notifica al componente Ver para que se actualice. Luego, en Ver, habrá métodos correspondientes para manejar las notificaciones de notificación y realizar el procesamiento lógico correspondiente.

El proxy solo envía notificaciones de notificación (cuando cambian los datos), no procesa notificaciones de notificación y no le importa cómo cambian los componentes de la vista.

El objeto Proxy no debe notificar al sistema que su DataObject (objeto de datos) ha cambiado al hacer referencia u operar el objeto Mediador.

En otras palabras, el Mediador puede obtener el Proxy, pero el Mediador no debe obtenerse en el Proxy. Si desea notificar a la capa de Vista para que se actualice, simplemente envíe una notificación de Notificación.

(Al proxy no le importa cómo afectarán estas notificaciones al sistema después de su emisión)

De esta manera, sólo existe un acoplamiento unidireccional entre Proxy y Mediator.

Proxy también contiene ciertas partes de procesamiento lógico: implementamos la lógica de dominio (lógica de dominio) en Proxy tanto como sea posible, para separar la capa Modelo de la capa de Vista asociada y la capa Controlador tanto como sea posible.

Por ejemplo, si implementa una función que calcula la deducción de impuestos en un Mediador o Comando, es equivalente a acoplar esta parte del código. Por ejemplo, su Vista debe reconstruirse u otros Comandos también deben usar la función de deducción de impuestos. Entonces esta parte del código no se puede reutilizar, por lo que es más apropiado ponerlo en Proxy.

Acerca de la conversión de tipos de datos

Debido a que el modelo (objeto de datos) suele ser una estructura de datos compleja, a menudo necesitamos hacer referencia a algunas de sus propiedades y convertir el tipo en los datos que necesitamos.

A través de las propiedades getter y setter, puede ayudarnos a resolver muy bien este problema frecuente de conversión de tipos.

Puede que sea necesario definir varios tipos diferentes de captadores para obtener determinadas partes del objeto de datos.

búsqueda pública de ArrayCollectionResultAC 

 obtener {devolver datos como ArrayCollection;}

 }

Este es un ejemplo del documento oficial, pero en el lado móvil, aún se recomienda almacenarlo en caché para evitar consumir memoria y provocar GC al convertir cada vez.

¿Qué son la vista y el mediador?

La vista es un componente de vista. Al igual que la capa Modelo, también se administra a través de un "mediador". La vista es un componente de vista específico (Componente de vista) operado por Mediador. Incluyendo: agregar detectores de eventos, enviar o recibir notificaciones y cambiar directamente el estado de los componentes de vista.

Mediador (patrón de diseño de mediador):

"Utilice un objeto intermediario para encapsular una serie de interacciones de objetos" (interacción intensa, lógica fuerte)

*Ver componente se refiere a varios controles en la interfaz de usuario, botones, listas, barras de desplazamiento, etc.

Hacer esto separa la vista de la lógica que la controla. La definición y la inicialización de los componentes en View se definen e implementan en Mediator, de modo que incluso si se reconstruye la interfaz de usuario, solo se cambia Mediator.

Debido a que Mediator también interactúa a menudo con Proxy, a menudo es necesario obtener una referencia a la instancia de Proxy en el constructor de Mediator y guardarla en las propiedades de Mediator, evitando así la sobrecarga de rendimiento causada por la obtención frecuente de instancias de Proxy.

Como puede ver aquí, generalmente existe una relación uno a uno entre la Vista y el Mediador, pero algunas Vistas son relativamente complejas y constan de múltiples sub-UI. Los mediadores también pueden tener múltiples referencias de componentes de vista (diferentes sub-UI para el misma función).

Pero si el Mediador es demasiado grande, es necesario dividirlo. Es mejor procesarlo en el Mediador del submódulo dividido que juntarlo todo. Esta parte del trabajo necesita ser reestructurada lentamente.

Convertir tipo de componente de vista

(Esta parte se maneja de la misma manera que el Modelo)

Esta subclase de Mediador pasará su parámetro Ver Componente a la clase principal en el constructor, y se asignará internamente a un atributo de protección: viewComponent, y se transferirá al tipo de Objeto.

Una vez construido el Mediador, puede asignar (modificar) dinámicamente su componente de vista llamando a su función setViewComponent. Después de eso, cada vez que necesite acceder a la API de este Objeto, deberá convertir manualmente el Objeto a su tipo real. Esta es una tarea tediosa y repetitiva.

Al igual que el modelo anterior, la referencia a la Vista se guarda en el Mediador y la almacenamos en caché.

Lo que suele hacer el mediador:

1. Verifique o modifique las propiedades de Ver componente

2. Verificar o modificar las propiedades publicadas por el objeto Proxy.

3. Enviar una o más Notificaciones para notificar a otros Mediadores o Comandos para que respondan (incluso puede enviarse a sí mismo).

Pero una cosa a tener en cuenta es que la lógica empresarial debe colocarse en el comando, no en el mediador.

De hecho, Mediator no maneja una lógica compleja. Al igual que el Modelo, la parte lógica del dominio se puede implementar en el Mediador, lo que reduce el acoplamiento con el Controlador y mejora la reutilización.

Nota: No considere la detección o modificación de las propiedades de VC (Ver componente y proxy) como lógica empresarial (lógica empresarial)

Aquí hay algunas lecciones útiles:

1. Si varios Mediadores responden al mismo evento, se debe enviar una Notificación y luego los Mediadores correspondientes responderán en consecuencia. (Modo observador)

(Por ejemplo, actualmente tiene 3 UI mostradas en la pantalla y cada UI muestra la cantidad de dinero del jugador. Cuando el dinero cambia, el Proxy debe enviar una notificación de notificación correspondiente y luego las 3 UI aceptan la notificación y continúan. Ver actualizaciones)

2. Si un Mediador necesita interactuar mucho con otros Mediadores, una buena manera es usar Comando para definir los pasos de interacción en un solo lugar.

3. No se debe permitir que un Mediador obtenga y llame directamente a otros Mediadores. Es incorrecto definir tal operación en un Mediador. Como puede ver en el diagrama conceptual anterior, no habrá comunicación directa entre Mediador y Mediador, lo que anula la intención original de reducir el acoplamiento.

Cuando los cambios en una Vista afecten a otro componente de Vista, simplemente envíe una notificación de Notificación.

4. El proxy tiene estado: cuando el estado cambia, envía una notificación para notificar al mediador y refleja los cambios de datos en el componente de vista.

Implemente estas "solicitudes" que se utilizan varias veces mediante comandos para hacerlas más independientes y mejorar la reutilización.

¿Patrón de diseño de proxy versus patrón de diseño de mediador?

Los dos patrones de diseño mencionados anteriormente hacen cosas muy similares, pero por definición, Proxy se enfoca más en controlar el acceso a los datos, lo que equivale a representar datos reales, mientras que Mediator se enfoca más en la interacción de datos (encapsulación) (interacción de una serie de objetos). Lógica fuerte, como el intermediario de la interacción entre AB, entonces la interacción con la interfaz de usuario es relativamente complicada y engorrosa, por lo que se utiliza Mediator para manejar las operaciones en la Vista.

Un ejemplo bastante bueno se da en "Dahua Design Pattern" para ilustrar al Mediador, es decir, las Naciones Unidas y organizaciones similares de protección ambiental. Los agentes inmobiliarios con los que tenemos contacto diario son responsables de la inspección, revisión, venta y pago de impuestos. , y transferencia de casas, etc. (interactivo, lógica fuerte) trabajo.

Si nos pidieran que contactáramos directamente con el propietario, no sólo tendríamos mucho conocimiento sino también riesgos legales.

Otro ejemplo es una tienda 4S. Vamos a la tienda 4S para ventas, posventa, etc. En el Mediador interactúan A y B. Tanto A como B "conocen" al mediador Mediador. Vamos a la tienda 4S, y La tienda 4S es responsable, habla con el fabricante del coche.

¿Qué son el controlador y el comando?

El controlador guarda el mapeo de todos los comandos. La clase Command no tiene estado y solo se crea cuando es necesario.

Aquí se utiliza el patrón de diseño Comando, que encapsula una "solicitud" y un "comportamiento" en un objeto, y encapsula la parte lógica de forma independiente para mejorar la reutilización. Las modificaciones a la Vista o Mediador no afectarán el Comando en sí. A través de la interfaz de nivel superior de Facade, Proxy, Mediator y Command pueden acceder y comunicarse entre sí.

El comando puede obtener e interactuar con objetos Proxy y Mediador, enviar notificaciones y ejecutar otros comandos. A menudo se utiliza para operaciones complejas o que afectan a todo el sistema, como el "inicio" y el "apagado" de aplicaciones. La lógica empresarial de la aplicación debe implementarse aquí.

Facade necesita inicializar el Controlador al inicio y establecer el mapeo entre Notificación y Comando.

El Controlador se registrará para escuchar cada Notificación. Cuando se notifique, el Controlador creará una instancia de un objeto de la clase Comando correspondiente a la Notificación. Finalmente, pase la Notificación como parámetro al método de ejecución. Para obtener más información, consulte la implementación de la clase base Command.

En otras palabras, la ejecución del Comando se realiza enviando una notificación de Notificación.

Los objetos de comando no tienen estado; se crean solo cuando son necesarios (el Controlador recibe la Notificación correspondiente) y se eliminan después de ser ejecutados (se llama al método de ejecución). Por lo tanto, no haga referencia al objeto Command en esos objetos de larga duración.

Durante la operación, puede inicializar Proxy y Mediator mediante Comando, es decir, registrarlos en Facade.

Por ejemplo:

clase pública ModelPrepCommand: SimpleCommand {

 // Llamado por MacroCommand

 anulación pública anulación Ejecutar (notificación INotificación) {

 IFacade.registerProxy (nuevo SearchProxy ());

 IFacade.registerProxy (nuevo PrefsProxy ());

 IFacade.registerProxy (nuevo UsersProxy ());

 }

(No publicaré una captura de pantalla de la parte de Comando aquí. Una vez que todos puedan entender el Modelo y el Mediador, la parte de Comando será más clara)

Dos tipos de comandos:

Command implementa la interfaz ICommand. Hay dos clases en PureMVC que implementan la interfaz ICommand: SimpleCommand y MacroCommand. SimpleCommand tiene solo un método de ejecución, que acepta una instancia de Inotification como parámetro. En aplicaciones prácticas, sólo es necesario anular este método.

MacroCommand le permite ejecutar múltiples comandos secuencialmente. Cada ejecución crea un objeto Comando y pasa una referencia a la Notificación de origen. MacroCommand llama a su propio método inicializeMacroCommand en el constructor. En la aplicación real, debe anular este método y llamar a addSubCommand para agregar un subCommand. Puede combinar SimpleCommand y MacroCommand en un nuevo comando.

Otros para presentar:

¿Lógica de Negocios (Lógica de Negocios) y Lógica de Dominio (Lógica de Dominio)?
 

Hay muchos lugares en su programa donde puede colocar código (Comando, Mediador y Proxy); inevitablemente se encontrará con la pregunta: ¿Qué código debe ir y dónde? ¿Qué debería hacer exactamente el Comando?

La lógica del programa se divide en lógica empresarial (lógica empresarial) y lógica de dominio (lógica de dominio). Primero, debe conocer la diferencia entre las dos.

La lógica empresarial (lógica empresarial) necesita coordinar el modelo y el estado de la vista (Ver).

El modelo garantiza la integridad y coherencia de los datos mediante el uso de Proxy. Proxy centraliza la lógica de dominio del programa y expone la API para operar objetos de datos. Encapsula todas las operaciones en el modelo de datos, independientemente de si los datos son del lado del cliente o del servidor, y si el acceso a los datos es síncrono o asíncrono para otras partes del programa.

Mediator y Proxy pueden proporcionar algunas interfaces de operación para que Command las llame para administrar ViewComponent y Model (objeto de datos), mientras ocultan los detalles de operaciones específicas de Command.

Observador 与 Notificación?

La comunicación de PureMVC se implementa de forma flexible usando el patrón Observer, un patrón de diseño casi omnipresente en el desarrollo de juegos. Solo necesita usar un método muy simple para enviar desde Proxy, Mediator, Command y Facade. Notificación, ni siquiera Es necesario crear una instancia de notificación.

Facade y Proxy solo pueden enviar notificaciones. Los mediadores pueden enviar y recibir notificaciones. La notificación se asigna al comando y el comando también puede enviar notificaciones. Este es un mecanismo de "publicación/suscripción" donde todos los observadores reciben la misma notificación. Por ejemplo, varios suscriptores de libros y publicaciones periódicas pueden suscribirse a la misma revista. Cuando se publique un nuevo número de la revista, se notificará a todos los suscriptores.

Facade guarda la asignación entre Comando y Notificación. Cuando se emita una Notificación, el Comando correspondiente será ejecutado automáticamente por el Controlador. El comando implementa interacciones complejas y reduce el acoplamiento entre Vista y Modelo.

Definir constantes de notificación

Cuando otros programas necesitan acceder a estas constantes de nombre de notificación, podemos usar una clase separada "ApplicationConstants" para almacenar estas definiciones de constantes de nombre de notificación. No importa cuándo, el nombre de la notificación debe definirse como una constante. Cuando necesite hacer referencia a una notificación, utilice su nombre constante. Esto puede evitar algunos errores que no se pueden encontrar durante la compilación. Debido a que el compilador puede verificar constantes; con cadenas, si ingresa la cadena incorrecta por error, el compilador no tiene forma de saberlo ni de informar un error.

Mediador envía, declara y recibe Notificación

Cuando un Mediador se registra con una Vista, se llamará al método listNotifications del Mediador para devolver todas las Notificaciones que le interesan al objeto Mediador en forma de matriz. Más adelante, cuando otros roles en el sistema emitan una Notificación con el mismo nombre, el Mediador que se preocupa por esta notificación llamará al método handleNotification y pasará la Notificación al método como parámetro.

Aquí el Mediador es el notificador. Cuando los datos del Proxy cambian, el Mediador recibe la notificación y actualiza la UI.

El proxy envía, pero no recibe la notificación

En muchas situaciones, el Proxy necesita enviar una Notificación (notificación), por ejemplo: cuando el Proxy recibe datos de un servicio remoto, envía una Notificación para informarle al sistema, o cuando los datos del Proxy se actualizan, envía una Notificación para notificar al componente de vista que se actualice. , etc.

Si al Proxy también se le permite escuchar la Notificación (notificación), hará que su acoplamiento con la capa Ver (Ver) y la capa Controlador (Control) sea demasiado alto.

La Vista y el Controlador deben escuchar la Notificación enviada por Proxy, porque su responsabilidad es permitir que los usuarios interactúen con los datos en poder de Proxy a través de una interfaz visual. Sin embargo, los cambios en la capa Vista y la capa Controlador no deberían afectar la capa Modelo.

Finalmente, hay un pequeño ejemplo de la interacción entre Ver Componente y Mediador en el documento:

Supongamos que hay un componente LoginPanel con un formulario. Existe un LoginPanelMediator correspondiente, que es responsable de interactuar con LoginPanel y enviar solicitudes de inicio de sesión en respuesta a su información de entrada.

La colaboración entre LoginPanel y LoginPanelMediator es la siguiente: LoginPanel envía un evento TRY_LOGIN cuando el usuario completa el ingreso de información y desea iniciar sesión. LoginPanelMediator maneja este evento enviando una notificación con el LoginVO contenido en el componente como "cuerpo del informe".

La parte LoginPanel.mxml se omite aquí y las partes de la vista son diferentes.

El componente LoginPanel contiene un objeto LoginVO recién creado con entrada de formulario de usuario. Cuando el usuario hace clic en el botón "Iniciar sesión", se activa un evento y LoginPanelMediator se hace cargo de lo siguiente.

De esta manera, la función de View Component es simplemente recopilar datos y notificar al sistema después de recopilarlos. Lo que se puede mejorar es hacer que el botón de inicio de sesión esté disponible (habilitado) solo cuando tanto el nombre de usuario como la contraseña tengan contenido, para evitar inicios de sesión maliciosos.

View Component oculta su implementación interna desde el exterior. Toda la API utilizada por Mediator incluye: un evento TRY_LOGIN, un atributo LoginVO y el atributo de estado del Panel.

Resumen final:
 

Existe una dependencia unidireccional entre la Vista y el Modelo: la Vista debe saber qué es el Modelo y la Vista también muestra el contenido de la vista en función de los datos del Modelo. Al modelo no le importa el contenido de la vista.

Proxy y Mediator son a la vez agentes y mediadores en sus responsabilidades, responsables de comunicarse con otros componentes. Y su registro se realiza por

Fachada para gestión unificada.

Proxy y Mediator no deben contener mucha lógica de negocios, la parte de la lógica de negocios debe manejarse en Command y algunas operaciones sobre los datos en sí deben colocarse en Proxy y Mediator.

Aunque se puede acceder y modificar cualquier Proxy en el Mediador, no se recomienda dejar que el Comando realice estas tareas para lograr un acoplamiento flexible entre la Vista y el Modelo. De esta manera, otras partes de la Vista pueden reutilizar el Comando.

 material:

Conexión oficial de GitHub: https://github.com/PureMVC

Sitio web oficial de PureMVC: www.puremvc.org

Blog: análisis de PureMVC_blog de Peter_Gao_-CSDN blog_puremvc

Blog: Aplicación del marco PureMVC en Unity (1) Blog-CSDN de _Peter_Gao_

Supongo que te gusta

Origin blog.csdn.net/qq_40097668/article/details/123987708
Recomendado
Clasificación