Cómo Cocoa aplica patrones de diseño
Cocoa a menudo basa sus mecanismos de trabajo distintivos en patrones, y su diseño está influenciado por factores como las capacidades del lenguaje o la arquitectura existente. Esta sección contiene una introducción a la mayoría de los patrones de diseño catalogados en el libro Patrones de diseño: elementos de software orientado a objetos reutilizable. Cada patrón de diseño tiene una descripción resumida y una discusión de la implementación de Cocoa del patrón. En este artículo se enumeran los patrones implementados por Cocoa, y la discusión de cada patrón ocurre en un entorno Cocoa específico. Le recomendamos que se familiarice con estos patrones, los encontrará muy útiles en el desarrollo de software Cocoa. La implementación de patrones de diseño en Cocoa se presenta de diferentes formas. Algunos de los diseños descritos en las siguientes secciones, como protocolos y categorías, son características del lenguaje Objective-C; en otros casos, una "instancia de un patrón" se implementa como una clase o un grupo de clases relacionadas (como; grupos de clases y clases únicas); en otros casos, el patrón aparece como una estructura de marco grande, como el patrón de cadena de respuesta. Algunas mecánicas basadas en patrones son prácticamente "gratuitas" para su uso; otras requieren algo de trabajo de su parte. Incluso para los patrones que Cocoa no implementa, le recomendamos que los implemente usted mismo si las condiciones lo permiten. Por ejemplo, al ampliar el comportamiento de una clase, la tecnología de composición de objetos (modo de decoración) suele ser mejor que generar subclases. Hay dos patrones de diseño que no se analizan a continuación, a saber, el patrón Modelo-Vista-Controlador (MVC) y el modelado de objetos. MVC es un patrón compuesto o de agregación, lo que significa que se basa en varios tipos diferentes de patrones. El modelado de objetos no tiene equivalente en la taxonomía de Quad y se origina en el mundo de las bases de datos relacionales. Sin embargo, MVC y el modelado de objetos son probablemente los patrones o términos de diseño más importantes y ubicuos en Cocoa, y están en gran medida relacionados. Desempeñan un papel clave en el diseño de varias tecnologías, incluido el enlace, la gestión de deshacer, el control de secuencias de comandos y la arquitectura de documentos. Para obtener más información sobre estos patrones, consulte las secciones "Patrones de diseño Modelo-Vista-Controlador" y "Modelado de objetos". Esta parte contiene los siguientes contenidos principales: Patrón de fábrica abstracto Patrón de adaptador Patrón de cadena de responsabilidad Patrón de comando Patrón compuesto Decoración Apariencia del patrón Patrón reductor Patrón de árbitro Patrón de nota Patrón de observador Patrón de agente Patrón singleton Patrón de método Patrón de fábrica abstracto proporciona una interfaz, utilizada para. crear una familia de clases que están relacionadas o dependientes de ciertos objetos sin especificar sus clases concretas. Este patrón desacopla el código del cliente de los detalles concretos del objeto de fábrica. Clúster de clases Un clúster de clases es una arquitectura que agrupa algunas subclases concretas privadas bajo una superclase abstracta pública. La superclase abstracta es responsable de declarar métodos para crear instancias de subclases privadas y asigna subclases concretas apropiadas según el método que se llama. Cada objeto devuelto puede pertenecer a una subclase privada diferente. Cocoa limita la agrupación de clases a la generación de objetos donde el almacenamiento de datos puede variar según el entorno. El marco Foundation define familias de clases para objetos NSString, NSData, NSDictionary, NSSet y NSArray. Las superclases públicas incluyen las clases inmutables mencionadas anteriormente y sus clases mutables complementarias NSMutableString, NSMutableData, NSMutableDictionary, NSMutableSet y NSMutableArray. Uso y limitaciones Cuando desee crear objetos mutables o inmutables del tipo representado por un grupo de clases, puede hacerlo utilizando una de las clases públicas en el grupo de clases. El uso de grupos de clases es un compromiso entre simplicidad y extensibilidad. Los clústeres de clases simplifican una interfaz de clase, haciéndola más fácil de aprender y usar, pero dificultan la creación de subclases personalizadas de la clase abstracta agrupada. Lectura adicional: la sección "Clústeres de clases" proporciona más información sobre los grupos de clases Cocoa. El patrón Adaptador convierte una interfaz de clase en otra interfaz requerida por el código del cliente. Los adaptadores permiten que las clases que no pueden funcionar juntas debido a la compatibilidad funcionen juntas, eliminando el acoplamiento entre el código del cliente y las clases del objeto de destino. Protocolos Un protocolo es una característica de nivel de lenguaje de programación (Objective-C) que permite definir instancias del patrón Adaptador ("interfaz" y "protocolo" son sinónimos en Java).
Si desea que un objeto cliente se comunique con otro objeto, pero tiene dificultades porque sus interfaces son incompatibles, puede definir un protocolo, que es esencialmente una serie de declaraciones de métodos que no están asociadas con una clase. De esta manera, otras clases de objetos pueden adoptar formalmente el protocolo y "seguirlo" implementando todos los métodos del protocolo. Como resultado, los objetos cliente pueden enviar mensajes a otros objetos a través de la interfaz del protocolo. Un protocolo es un conjunto de declaraciones de métodos que son independientes de la jerarquía de clases, lo que permite agrupar objetos según los protocolos que siguen, al igual que la herencia de clases. Puede confirmar la relación de protocolo de un objeto a través del método conformsToProtocol: de NSObject. Además de los acuerdos formales, Cocoa también tiene el concepto de acuerdos informales. Este tipo de protocolo es una categoría dentro de la clase NSObject, lo que convierte a todos los objetos en implementadores potenciales de los métodos de categoría (consulte la sección "Categorías"). Opcionalmente se puede implementar el enfoque de acuerdo informal. Un protocolo informal es parte de la implementación del mecanismo de delegación (consulte la sección "Delegados". Tenga en cuenta que el diseño del protocolo no coincide exactamente con el patrón del Adaptador. Pero es un medio para permitir que clases con interfaces incompatibles trabajen juntas. Uso y restricciones del protocolo Se utiliza principalmente para declarar interfaces que las clases jerárquicamente no relacionadas deben seguir para comunicarse entre sí. Sin embargo, también puede utilizar protocolos para declarar la interfaz de un objeto y ocultar la clase correspondiente. El marco incluye una serie de protocolos formales. Las subclases personalizadas pueden comunicarse con el marco para propósitos específicos. Por ejemplo, el marco Foundation incluye los protocolos NSObject, NSCopying y NSCoding, y los protocolos en el kit de aplicación incluyen NSDraggingInfo, NSTextInput y NSChangeSpelling. Cumplimiento del protocolo formal. Implemente todos los métodos declarados por un protocolo. También están fragmentados, y una vez que define un protocolo y lo proporciona a otras clases, las modificaciones futuras del protocolo romperán esas clases. protocolos formales: discusión en la sección "Clases extendidas" de la documentación del lenguaje de programación C. El patrón Cadena de responsabilidad evita acoplar el remitente y el receptor de una solicitud encadenando los objetos receptores y enrutando la solicitud a lo largo del receptor. cadena hasta que un objeto maneja la solicitud o la pasa al siguiente objeto de la cadena. El marco del kit de aplicación incluye una estructura llamada cadena de respuesta. La cadena consta de una serie de objetos de respuesta (es decir, objetos heredados de NSResponder). Los eventos (como clics del mouse) o mensajes de acción se pasan a lo largo de la cadena y (generalmente) finalmente son procesados por el respondedor dado. El objeto no procesa un mensaje específico, sino que pasa el mensaje al siguiente respondedor de la cadena. El orden de los respondedores en la cadena generalmente está determinado por la jerarquía de la vista, desde los objetos de respuesta de nivel inferior hasta los objetos de nivel superior. Pasando, el vértice es el objeto de ventana que administra la jerarquía de vista, el objeto delegado del objeto de ventana o el. objeto de aplicación global. La ruta exacta que toman los mensajes de eventos y acciones en la cadena de respuesta varía de una aplicación a otra. Una cadena de respuesta puede tener tantas ventanas (o incluso ver objetos en la jerarquía local) como posee, pero solo un respuesta. La cadena está activa a la vez: la asociada con la ventana actualmente activa. Hay una cadena similar a la cadena de respuesta para el manejo de errores en la aplicación. La jerarquía de vistas está diseñada utilizando el patrón de composición (consulte la sección "Patrón compuesto"). , que está estrechamente relacionado con la cadena de respuesta, derivada de mensajes de acción para objetos de control, basados en el mecanismo de acción objetivo y son una instancia del patrón de comando (consulte la sección "Patrón de comando" Usos y limitaciones disponibles "). gratis" cuando construye una interfaz de usuario para un programa a través de Interface Builder o mediante programación. Obtenga una o más cadenas de respuesta. La cadena de respuesta va junto con la jerarquía de vistas, que se genera automáticamente cuando convierte un objeto de vista en una subvista de la vista de contenido de la ventana.
Si agrega una vista personalizada a una jerarquía de vistas, se convierte en parte de la cadena de respuesta; si implementa los métodos NSResponder apropiados, puede recibir y manejar mensajes de eventos y acciones. El objeto personalizado es un objeto delegado al objeto de ventana o al objeto de aplicación global NSApp y también puede recibir y procesar esos mensajes. También puede inyectar mediante programación objetos de respuesta personalizados en la cadena de respuesta y manipular mediante programación el orden de los respondedores en la cadena. Lectura adicional: La cadena de respuesta para manejar mensajes de eventos y acciones y errores de programa se describe en los documentos Cocoa Event Handling Guide y Cocoa Error Handling Programming Guide. Este documento proporciona un resumen de las jerarquías de vistas en la sección "Patrones compuestos" y una descripción más completa en la sección "Arquitectura de aplicación principal". Patrón de comando Este patrón encapsula solicitudes como objetos, lo que le permite parametrizar el código del cliente con diferentes solicitudes en cola y registra solicitudes, y admite operaciones que se pueden deshacer; El objeto de solicitud vincula una o más acciones a un destinatario específico. El patrón de comando distingue entre el objeto que realiza la solicitud y el objeto que recibe y ejecuta la solicitud. Las instancias de la clase NSInvocation del objeto de llamada se utilizan para encapsular mensajes de Objective-C. Un objeto de llamada contiene un objeto de destino, un selector de método y parámetros de método. Puede cambiar dinámicamente el destino del mensaje y sus parámetros en el objeto que llama y, una vez que se ejecuta el mensaje, puede obtener el valor de retorno del objeto. Los mensajes con diferentes objetivos o parámetros se pueden llamar varias veces a través de un objeto de llamada. La creación de un objeto NSInvocation requiere el uso de un objeto NSMethodSignature, que es responsable de encapsular información relacionada con los parámetros del método y los valores de retorno. La creación de objetos NSMethodSignature requiere el uso de un selector de métodos. La implementación de NSInvocation también utiliza algunas funciones del entorno de ejecución de Objective-C. Uso y restricciones Los objetos NSInvocation son parte de las interfaces de programación de objetos distribuidos, de gestión de deshacer, de mensajería y de temporizador. También puede usarlo en situaciones similares en las que necesite eliminar la relación de acoplamiento entre el objeto que envía el mensaje y el objeto que lo recibe. Los objetos distribuidos son una tecnología de comunicación entre procesos; consulte la sección "Patrón de agente" para obtener más información sobre este tema. Lectura adicional: lea la documentación de referencia de la clase NSInvocation para obtener detalles sobre el objeto de invocación. También puede obtener información sobre tecnologías relacionadas en: objetos distribuidos, arquitectura de deshacer, temporizadores y más en la documentación del lenguaje de programación Objective-C. Acción de destino El mecanismo de acción de destino permite que un objeto de control (es decir, un objeto como un botón o un cuadro de entrada de texto) envíe un mensaje a otro objeto que pueda interpretar el mensaje y procesarlo en instrucciones específicas de la aplicación. El objeto receptor, u objetivo, suele ser un objeto controlador personalizado. Los mensajes, también llamados mensajes de acción, se identifican mediante un selector, que es un identificador de tiempo de ejecución único para un método. Normalmente, el objeto de unidad propiedad de un control encapsula un objetivo y una acción para enviar un mensaje cuando el usuario hace clic o activa el control (los elementos del menú también encapsulan un objetivo y una acción para enviar un mensaje de acción cuando el usuario lo selecciona). La razón por la que el mecanismo de acción objetivo puede basarse en selectores (en lugar de firmas de métodos) es porque Cocoa estipula que la firma del método de acción y el nombre del selector son siempre los mismos. Uso y limitaciones Cuando utiliza Interface Builder para crear la interfaz de usuario de su programa, puede establecer las acciones y objetivos de los controles. Por lo tanto, puede personalizar el comportamiento del control sin tener que escribir ningún código para el control en sí. Los selectores de acciones y las conexiones de destino se archivan en el archivo nib y se resucita cuando se desarchiva el archivo nib. También puede cambiar dinámicamente objetivos y acciones enviando mensajes setTarget: y setAction: al control o su objeto de unidad. El mecanismo de acción objetivo se utiliza a menudo para notificar a los objetos de controlador personalizados que pasen datos desde la interfaz de usuario a los objetos del modelo, o para que muestren datos de los objetos del modelo. La tecnología de unión de cacao puede evitar este uso. Para obtener más información sobre esta tecnología, consulte la documentación del tema de programación de unión de cacao. Los controles y unidades del kit de aplicación no mantienen su objetivo. En cambio, mantienen una débil referencia al objetivo.
Consulte la sección "Propiedad de los delegados, observadores y objetivos" para obtener más información. Lectura adicional: consulte la sección "Mecánica de acción objetivo" para obtener más información. Modo compuesto Este modo combina objetos interrelacionados en una estructura de árbol para representar jerarquías de parte a todo. Permite que el código del cliente maneje de manera uniforme objetos individuales y los resultados compuestos de múltiples objetos. Los objetos compuestos son parte del patrón de agregación Modelo-Vista-Controlador. Jerarquía de vistas Los objetos de vista (objetos NSView) contenidos en una ventana forman internamente una jerarquía de vistas. La raíz de la jerarquía es el objeto de ventana (objeto NSWindow) y sus vistas de contenido. La vista de contenido es una vista transparente que se completa en el cuadro de contenido de la ventana. Las vistas agregadas a la vista de contenido son todas sus subvistas, y estas subvistas se convertirán en las vistas principales de las vistas del siguiente nivel. Una vista tiene una (y sólo una) vista principal y puede tener cero o más vistas secundarias. Visualmente, puede entender esta estructura como una relación de contención: una vista principal contiene sus vistas secundarias. La Figura 4-2 muestra la estructura de la jerarquía de vistas y sus relaciones visuales. Figura 4-2 La estructura de la jerarquía de vistas y su relación visual La jerarquía de vistas es una arquitectura estructural que desempeña un papel determinado en la representación de gráficos y el procesamiento de eventos. Una vista tiene dos cuadros delimitadores que afectan la posición de las operaciones gráficas, a saber, marco y límite. El borde es el límite exterior y representa la posición de la vista en el sistema de coordenadas de su vista principal. Es responsable de definir el tamaño de la vista y recortar los gráficos de acuerdo con el límite de la vista. Los límites son el cuadro delimitador interno que define el sistema de coordenadas interno de la propia superficie de dibujo del objeto de vista. Cuando el sistema de ventanas solicita que una ventana esté lista para mostrarse, se solicita a la vista principal que se represente antes que las vistas secundarias. Cuando envía un mensaje a una vista, como un mensaje para volver a dibujar la vista, el mensaje se propaga a las subvistas. Por lo tanto, puede tratar una rama en la jerarquía de vistas como una vista unificada. La cadena de respuesta también utiliza la jerarquía de vistas para manejar mensajes de eventos y acciones. Consulte la sección Patrón de cadena de responsabilidad ("Patrón de cadena de responsabilidad") para obtener una descripción resumida de la cadena de respuesta. Uso y limitaciones Ya sea mediante programación o mediante Interface Builder, usted crea o modifica una jerarquía de vistas cuando une una vista a otra. El marco del kit de aplicaciones maneja automáticamente todas las relaciones asociadas con las jerarquías de vistas. Lectura adicional: si necesita más información sobre las jerarquías de vistas, lea la sección "Jerarquías de vistas" de este documento. La jerarquía de vistas también se analiza en el documento Pautas de dibujo de cacao. Patrón de decoración Este patrón asigna dinámicamente responsabilidades adicionales a un objeto. La decoración es una alternativa flexible a la subclasificación al ampliar la funcionalidad. Al igual que las subclases, adoptar el patrón de decoración le permite agregar nuevos comportamientos sin modificar el código existente. La decoración envuelve un objeto de una clase que necesita ser extendida, implementa la misma interfaz que el objeto y agrega su propio comportamiento antes o después de pasar la tarea al objeto envuelto. El patrón Decorator expresa el principio de diseño de que las clases deben aceptar extensiones pero evitar modificaciones. Descripción general La decoración es un patrón para la composición de objetos. Se debe fomentar la composición de objetos en su propio código (consulte la sección "Cuándo es necesaria la subclasificación"). Sin embargo, el propio Cocoa proporciona algunas clases y mecanismos basados en este patrón (que se analiza en la siguiente sección). En estas implementaciones, el objeto de extensión no copia completamente la interfaz del objeto que envuelve, aunque se pueden usar diferentes técnicas en implementaciones específicas para compartir la interfaz. Cocoa usa el modo de decoración al implementar ciertas clases, incluidas NSAttributedString, NSScrollView y NSTableView. Las dos últimas clases son ejemplos de vistas compuestas, que combinan objetos de otras clases de vista y luego coordinan las interacciones entre ellos. Delegación La delegación incorpora una referencia débil (una variable de socket no mantenida) que apunta a otro objeto (es decir, el objeto delegado) en el objeto host y envía mensajes al objeto delegado de vez en cuando para permitirle ingresar tareas relacionadas. Un objeto host es generalmente un objeto de marco "resucitado" (como un objeto NSWindow o NSXMLParser) que busca completar un determinado trabajo, pero solo puede hacerlo de manera general.
Un delegado es casi siempre una instancia de una clase personalizada que es responsable de trabajar con el objeto host para proporcionar un comportamiento específico del programa en puntos específicos de la tarea (consulte la Figura 4-3). De esta forma, el mecanismo de delegación nos permite modificar o ampliar el comportamiento de otro objeto sin necesidad de generar una subclase. Figura 4-3 Un objeto de marco envía un mensaje a su objeto delegado. En resumen, la delegación es cuando un objeto delega una tarea a otro objeto. Es una técnica común en la programación orientada a objetos. Sin embargo, Cocoa implementa el mecanismo de delegación de una manera única. La clase de host utiliza protocolos informales (categorías en NSObject) para definir las interfaces que el objeto delegado puede elegir implementar. Un objeto delegado no tiene que implementar todos los métodos de protocolo como si estuviera adoptando un protocolo formal. Antes de enviar un mensaje al objeto delegado, el objeto host primero puede determinar si el método correspondiente está implementado (a través del mensaje respondeToSelector:) para evitar excepciones en tiempo de ejecución. Consulte la sección "Acuerdo" para obtener más información sobre acuerdos formales e informales. Algunas clases en el marco Cocoa también envían mensajes a sus fuentes de datos. Una fuente de datos es como un delegado en todos los aspectos, excepto que su propósito es proporcionar datos al objeto host para su entrega al navegador, vista de tabla o vista de interfaz de usuario similar. A diferencia de los delegados, las fuentes de datos también deben implementar ciertos métodos de protocolo. Los delegados no son una implementación estricta del patrón decorador. El objeto anfitrión (delegado) no envuelve una instancia de la clase que desea extender. En cambio, la delegación es una especialización del comportamiento de una clase marco delegada. Además de los métodos delegados declarados por la clase marco, tampoco tienen una interfaz pública. Los delegados en Cocoa también son parte del patrón Método de plantilla ("Patrón de método de plantilla"). Usar y limitar delegados es un diseño común en el marco Cocoa. Muchas clases en el marco del kit de aplicaciones envían mensajes a sus delegados, incluidas NSApplication, NSWindow y varias subclases de NSView. Algunas clases en el marco Foundation, como NSXMLParser y NSStream, también mantienen sus propios delegados. Siempre debe utilizar el mecanismo de delegación de una clase en lugar de subclasificar una clase, a menos que el método de delegación no logre sus objetivos. Aunque puede cambiar delegados dinámicamente, sólo un objeto puede ser delegado a la vez. Por lo tanto, si desea que se notifique a varios objetos simultáneamente cuando ocurre un evento de programa específico, no puede utilizar delegados. En este caso puedes utilizar el mecanismo de notificación. Si el objeto delegado implementa uno o más métodos de notificación declarados por la clase de marco, recibirá automáticamente notificaciones de su objeto de marco delegado. Consulte la discusión sobre notificaciones en el Patrón de Observador ("Patrón de Observador"). Los objetos en el marco del kit de aplicaciones que delegan tareas no conservan su delegado o fuente de datos, pero mantienen una referencia débil. Para obtener más información, consulte la sección "Propiedad de delegados, observadores y objetivos". Lectura adicional: consulte la sección "Delegados y fuentes de datos" para obtener más información sobre los delegados. Categorías Las categorías son una característica del lenguaje Objective-C que se utilizan para agregar métodos (interfaces e implementaciones) a una clase sin tener que generar subclases. No hay diferencia en tiempo de ejecución entre los métodos declarados originalmente por una clase y los métodos agregados a través de categorías, dentro del alcance de su programa. Los métodos de la categoría pasan a formar parte del tipo de clase y son heredados por todas las subclases. Al igual que los delegados, las categorías no se ajustan estrictamente a los patrones de decorador. Logra el propósito del patrón, pero de una manera diferente. El comportamiento de unión de categorías se genera en tiempo de compilación, no se obtiene dinámicamente. Además, la categoría no encapsula instancias de la clase extendida. Uso y limitaciones Hay muchas categorías definidas en el marco de Cocoa, la mayoría de las cuales son acuerdos informales (resumidos en la sección "Protocolos"). A menudo utilizan categorías para agrupar métodos relacionados. También puede implementar categorías en su código para extender una clase sin subclases o para agrupar métodos relacionados. Pero es necesario tener en cuenta los dos puntos siguientes: No se pueden agregar variables de instancia a una clase. Si sobrecarga un método existente, su aplicación puede comportarse inesperadamente. Lectura adicional: para obtener más información sobre las categorías, consulte la sección "Extensiones de clases" del artículo sobre lenguaje de programación Objective-C. Patrón aparente Este patrón proporciona una interfaz unificada para un conjunto de interfaces en un subsistema.
El patrón aparente define una interfaz de nivel superior que hace que los subsistemas sean más fáciles de usar al reducir la complejidad y ocultar la comunicación y las dependencias entre los subsistemas. NSImage La clase NSImage proporciona una interfaz unificada para cargar y usar imágenes basadas en mapas de bits (como formatos JPEG, PNG o TIFF) o vectores (formatos EPS o PDF). NSImage puede mantener múltiples representaciones de la misma imagen, y diferentes representaciones corresponden a diferentes tipos de objetos NSImageRep. NSImage puede seleccionar automáticamente una representación apropiada para un tipo de datos y un dispositivo de visualización en particular. Al mismo tiempo, oculta los detalles de manipulación y selección de imágenes, lo que permite que el código del cliente utilice muchas representaciones diferentes de manera intercambiable. Uso y limitaciones Debido a que NSImage admite varias representaciones de imágenes diferentes, es posible que algunas propiedades no se apliquen. Por ejemplo, es posible que no pueda obtener el color de un píxel en una imagen si la representación de la imagen subyacente está basada en vectores y es independiente del dispositivo. Tenga en cuenta: consulte la Guía de dibujo de Cocoa para obtener información sobre NSImage y la representación de imágenes. Patrón iterador Este patrón proporciona una manera de acceder secuencialmente a los elementos de un objeto agregado (es decir, una colección) sin exponer la representación subyacente. El patrón Iterador transfiere la responsabilidad de acceder y recorrer los elementos de la colección desde el objeto de la colección al objeto iterador. Los iteradores definen una interfaz para acceder a los elementos de la colección y realizar un seguimiento del elemento actual. Diferentes iteradores pueden implementar diferentes estrategias transversales. La clase NSEnumerator en el marco NSEnumeratorFoundation implementa el patrón iterador. Las subclases privadas concretas de la clase abstracta NSEnumerator devuelven objetos enumeradores que pueden iterar secuencialmente sobre colecciones de diferentes tipos (matrices, conjuntos, diccionarios (valores y claves)) y devolver los objetos de la colección al código del cliente. NSDirectoryEnumerator es una clase poco relacionada cuyas instancias pueden enumerar de forma recursiva el contenido de los directorios en un sistema de archivos. Uso y limitaciones Las clases de colección, como NSArray, NSSet y NSDictionary, contienen métodos que devuelven enumeradores apropiados para el tipo de colección. Todos los enumeradores funcionan de la misma manera. Puede enviar un mensaje nextObject al enumerador en un bucle y salir del bucle si el mensaje devuelve nil en lugar del siguiente objeto de la colección. El patrón Arbiter define un objeto que encapsula el mecanismo de interacción de un grupo de objetos. El patrón Arbiter evita referencias mutuas explícitas entre objetos, afloja el acoplamiento entre objetos y le permite cambiar de forma independiente la forma en que interactúan. Por tanto, estos objetos pueden ser más reutilizables. Los objetos árbitro centralizan la comunicación compleja y la lógica de control entre los objetos del sistema. Estos objetos le dicen al objeto árbitro cuando cambia el estado y, a su vez, responden a las solicitudes del objeto árbitro. El patrón de diseño Modelo-Vista-Controlador de clase de controlador asigna diferentes roles a los objetos en un sistema orientado a objetos (como una aplicación). Pueden ser objetos modelo, que contienen los datos de la aplicación y operan con esos datos; pueden ser objetos de vista, que son responsables de representar los datos y responder a las acciones del usuario, o pueden ser objetos controladores, que son responsables de coordinar el modelo y la vista; objetos. Los objetos del controlador encajan en el patrón Arbiter. En Cocoa, generalmente existen dos tipos de objetos controladores: controladores de arbitraje o controladores de coordinación. Los controladores de arbitraje son responsables de arbitrar el flujo de datos entre los objetos de vista y los objetos de modelo en una aplicación. El controlador de arbitraje suele ser un objeto NSController. El controlador de coordinación es responsable de implementar la lógica de control y comunicación centralizada de la aplicación, sirviendo como delegado para los objetos del marco y el objetivo de los mensajes de acción. Suelen ser instancias de objetos NSWindowController o subclases NSObject personalizadas. Dado que el controlador de coordinación está altamente especializado para un programa específico, no se considera la reutilización. La clase abstracta NSController y sus subclases concretas en el marco del kit de aplicaciones son parte de la tecnología de enlace Cocoa, que puede sincronizar automáticamente los datos contenidos en el objeto modelo y los datos mostrados y editados en el objeto de vista. Por ejemplo, si el usuario edita una cadena en un cuadro de texto, la tecnología de enlace propagará los cambios en el cuadro de texto (a través del controlador de arbitraje) a las propiedades apropiadas en el objeto del modelo enlazado.
Lo que los programadores deben hacer es diseñar correctamente sus propios objetos modelo y establecer relaciones vinculantes entre las vistas, los controladores y los objetos modelo del programa a través de Interface Builder. Hay instancias de clases de controladores públicos específicas disponibles en la paleta de control de Interface Builder, lo que las hace altamente reutilizables. Proporcionan servicios como la selección y gestión de valores de marcador de posición. Estos objetos realizan las siguientes funciones específicas: NSObjectController gestiona un único objeto de modelo. NSArrayController administra una matriz de objetos modelo y mantiene una selección; también puede agregar o eliminar objetos modelo de la matriz. NSTreeController le permite agregar, eliminar y administrar objetos del modelo en una estructura de árbol jerárquica. NSUserDefaultsController proporciona una interfaz conveniente para el sistema de aprovisionamiento (valores predeterminados del usuario). Uso y limitaciones Normalmente puede utilizar objetos NSController como controladores de arbitraje porque estos objetos están diseñados para pasar datos entre los objetos de vista y los objetos de modelo de su aplicación. Cuando se utiliza un controlador de arbitraje, generalmente se arrastra el objeto desde la paleta de Interface Builder, se especifican las claves de propiedad del objeto de modelo y se establece la relación de enlace entre la vista y el objeto de modelo a través del panel Enlaces en la ventana de información de Interface Builder. También puede crear subclases de NSController o sus subclases para un comportamiento más específico. Se puede establecer una relación vinculante entre casi cualquier par de objetos siempre que sigan los dos protocolos informales NSKeyValueCoding y NSKeyValueObserving. Sin embargo, le recomendamos que establezca enlaces a través de un controlador de quórum para aprovechar los beneficios que le brindan NSController y sus subclases. Los controladores de coordinación centralizan la comunicación y la lógica de control de una aplicación manteniendo variables de socket que apuntan a objetos de modelo y visualización (las variables de socket son conexiones o referencias a otros objetos que se mantienen como variables de instancia). Responda a las operaciones del usuario en el objeto de vista a través del mecanismo de acción de objetivo (consulte la sección "Acción de objetivo"). Como objeto delegado, maneja los mensajes enviados desde el objeto del marco (consulte la sección "Delegados"). Por lo general, realiza las conexiones descritas anteriormente (variables de salida, acciones de destino y delegados) en Interface Builder, que archiva estas conexiones en el archivo nib de su aplicación. Lectura adicional: Consulte la sección "Patrón de diseño Modelo-Vista-Controlador" para obtener una discusión sobre controladores de arbitraje, controladores de coordinación y decisiones de diseño relacionadas con el controlador. Patrón Memento Este patrón captura y externaliza el estado interno de un objeto para que luego el objeto pueda restaurarse a ese estado sin romper la encapsulación. El patrón memo exterioriza el estado importante de los objetos clave mientras mantiene la cohesión de los objetos. Archivos Los archivos almacenan objetos en un programa y sus atributos (incluidos atributos y relaciones) en archivos para que puedan guardarse en el sistema de archivos o transferirse entre diferentes procesadores y redes. Un archivo guarda el gráfico de objetos de un programa como un flujo de bytes independiente de la arquitectura. Se conservan las identidades de los objetos y las relaciones entre ellos. Dado que el tipo de objeto se almacena junto con sus datos, el objeto decodificado del flujo de bytes archivado se crea una instancia normalmente, utilizando la misma clase que la clase codificada originalmente. Uso y limitaciones Normalmente, desea archivar objetos en su programa que requieren un estado guardado. Los objetos modelo casi siempre entran en esta categoría. Usted escribe objetos en el archivo mediante codificación y lee objetos del archivo mediante decodificación. Las operaciones de codificación y decodificación se pueden realizar a través del objeto NSCoder. Es mejor utilizar tecnología de archivo con clave durante el proceso de codificación y decodificación (debe llamar a los métodos de las clases NSKeyedArchiver y NSKeyedUnarchiver). El objeto que se codifica y decodifica debe cumplir con el protocolo NSCoding; los métodos de este protocolo se llamarán durante el proceso de archivado. Lectura adicional: Más información sobre el archivo. Serialización de listas de propiedades Una lista de propiedades es una secuencia simple y estructurada de gráficos de objetos que utiliza solo objetos de las siguientes clases: NSDictionary, NSArray, NSString, NSData, NSDate y NSNumber.
Estos objetos también suelen denominarse objetos de lista de propiedades. Hay varias clases de marco en Cocoa que proporcionan métodos para serializar objetos de lista de propiedades y definir formatos de flujo de datos especiales para registrar el contenido de los objetos y sus relaciones jerárquicas. La clase NSPropertyListSerialization proporciona métodos de clase para serializar objetos de la lista de propiedades en XML u otros formatos binarios optimizados. Uso y limitaciones Si su gráfico de objetos contiene objetos simples, la serialización de la lista de propiedades es una herramienta flexible, portátil y apropiada para capturar y externalizar objetos y su estado. Sin embargo, esta forma de serialización tiene sus limitaciones. No conserva toda la identidad de clase del objeto, sino sólo algunos tipos generales (matrices, diccionarios, cadenas, etc.). De esta manera, el objeto restaurado de la lista de atributos puede ser diferente de la clase original, lo que puede causar problemas, especialmente cuando la mutabilidad del objeto puede cambiar. La serialización de la lista de propiedades tampoco rastrea objetos a los que se hace referencia varias veces en el mismo objeto, lo que puede dar como resultado múltiples instancias al deserializar, pero solo una instancia en el gráfico de objetos original. Lectura adicional: Más información sobre la serialización de la lista de propiedades. Core DataCore Data es un marco y una arquitectura para gestionar gráficos de objetos y conservarlos. Es esta segunda habilidad (la capacidad de persistir objetos) la que hace de Core Data una adaptación del patrón memo. En la arquitectura Core Data, el objeto central se denomina contexto de objeto administrado, que es responsable de administrar los objetos del modelo en el gráfico de objetos de la aplicación. Debajo del contexto del objeto administrado se encuentra la pila de persistencia del gráfico de objetos, que es una colección de objetos de marco responsables de coordinar los objetos del modelo con almacenes de datos externos, como archivos XML o bases de datos relacionales. El objeto de pila persistente es responsable de establecer la relación de mapeo entre los datos en el almacenamiento y los objetos en el contexto del objeto administrado. Cuando hay varios almacenes de datos, el objeto de pila persistente representa estos almacenes como un almacenamiento agregado en el contexto del objeto administrado <. /p>