2011-07-31 5 views

Respuesta

7

Imagine que le pido que haga algunas tareas, como pintar una habitación. Si le digo "pintar una habitación", tendrá que hacerme muchas preguntas, como:

  • ¿Qué habitación?
  • ¿Dónde está la pintura?
  • ¿Dónde están los pinceles?
  • ¿Debo usar una toalla de tela?

En resumen, no podrá completar la tarea sin mi ayuda. Si tienes que depender de mí cada vez, no serás un pintor muy flexible. Una forma de lidiar con ese problema es que yo le dé todo lo que necesita al principio. En lugar de "ir a pintar una habitación", diré "pinten la habitación número 348 con este balde de pintura y este pincel, y no se molesten con un trapo". Ahora, tiene todo lo que necesita y puede ponerse a trabajar sin ayuda de mí. Eres un trabajador mucho más flexible porque ya no dependes de mí.

Lo mismo se aplica a los controladores de visualización (y objetos en general); es mejor darles todo lo que necesitan que depender de un objeto en particular como el delegado de la aplicación. Es cierto no solo para contextos de objetos administrados, sino también para cualquier información que necesiten para hacer su trabajo.

3

Esto se debe principalmente a que desea utilizar dependency injection con sus UIViewControllers en lugar de simplemente tomar todo de UIApplication, esto mantiene su delegado limpio en lugar de lleno de hacks de referencia.

Esto es también para mantener con el patrón MVC:

  1. Modelo

  2. View Controller (Sólo para vista lógica)

  3. Controller (Para la coordinación entre la vista y el modelo)

2

Tiendo a no estar de acuerdo con este pa Ttern.

En primer lugar, trato de tratar los datos centrales como un detalle de implementación, y como cualquier detalle de implementación, debe ocultarse detrás de una buena fachada. La fachada son las interfaces que expongo para mis objetos modelo. Por ejemplo, si tengo dos objetos modelo; Cource y Student, cualquier fuente puede tener un número de estudiantes. No quiero permitir que el controlador asuma el deber de configurar predicados y ordenar descriptores, y pasar por todos los niveles de datos básicos solo para obtener una lista de estudiantes para una clase en particular. Hay una forma perfectamente válida para exponer esto en el modelo:

@interface Cource (StudentAccess) 
-(NSArray*)studentsStortedByName; 
@end 

luego implementar las cosas feas de una vez por todas en la clase del modelo. Ocultando todos los detalles complejos de Core Data, y sin necesidad de pasar por contextos de objetos gestionados. ¿Pero cómo encontraría las fuentes, tiene que comenzar en algún lugar, cierto? Sí, lo hace, pero no necesita exponerlo al controlador. Agregar métodos como estos también es perfectamente razonable:

@interface Cource (CourceAccess) 
+(Cource*)caurceByID:(NSString*)courceID; 
+(NSArray*)allCources; 
+(NSArray*)courcesHeldByTeacher:(Teacher*)teacher; 
@end 

Esto también ayuda a minimizar las dependencias entre los controladores. Y reduciendo las dependencias entre el modelo y el controlador. Suponiendo que tengo una CourceViewController y una StudenViewController es que no ocultar los detalles de Datos Básicos detrás de una fachada y quería pasar todo el contexto de objeto gestionado así, entonces me gustaría terminar con un inicializador designado como esto:

-(id)initWithManagedObjectContext:(NSManagedObjectContext*)moc 
          student:(Student*)student; 

Mientras que con una buena buena fachada termino con esto:

-(id)initWithStudent:(Student*)student; 

Reducir al mínimo las dependencias detrás de fachadas, a favor de la inyección de dependencia también hace que sea mucho más fácil para cambiar las implementaciones internas. Pasar el contexto del objeto gestionado alienta a cada controlador a implementar su propia lógica para cosas básicas. Tome por ejemplo el método studentsSortedByName. Al principio podría ser un clasificador por apellido/nombre, si luego se cambiara por apellido/nombre, tendrías que dirigirte a todos y cada uno de los controladores que hayan ordenado a los estudiantes y realicen el cambio.Donde un buen método de fachada requiere que cambie en un método, y todos los controladores automáticamente obtienen la actualización de forma gratuita.

+0

No veo dónde estás en desacuerdo con Apple; solo estás dando un paso más y ocultando el contexto. No recomendaría que su controlador de vista obtenga la lista de estudiantes o cursos del delegado de la aplicación u otro singleton, ¿verdad? – Caleb

+0

@Caleb - No, no del delegado de la aplicación, pero no me daría vergüenza sacar una lista de cursos de un método de clase de la clase 'Curso'. Tratando la clase como un singleton de tipo. – PeyloW

+1

No estoy de acuerdo en que los géneros y los predicados pertenecen a la capa del modelo. Las ordenaciones y los predicados solo son requeridos por la interfaz, por lo que pertenecen al controlador. Colocar ordenaciones y predicados en el modelo vincula el modelo a una interfaz particular y contamina la integridad lógica de la simulación del modelo de los objetos, eventos o condiciones del mundo real que trata la aplicación. – TechZen

1

Los Apple Docs intentan fomentar los patrones de diseño más aplicables y sostenibles. Se prefiere la inyección de dependencia porque permite el diseño más flexible, ampliable, reutilizable y mantenible.

A medida que las aplicaciones crecen en complejidad, el uso de un cuasi sencillo como estacionar el contexto en el delegado de la aplicación se rompe. En aplicaciones más complejas, puede tener múltiples contextos vinculados a múltiples tiendas. Es posible que desee el mismo par vista/controlador/vista para visualizar datos de diferentes contextos en diferentes momentos o puede terminar con múltiples contextos en diferentes hilos/operaciones. No puedes acumular todo ese contexto en el delegado de la aplicación.

Si tiene una aplicación sencilla con un contexto único, puede ser útil usar el cuasi singleton con el delegado de la aplicación. Lo he usado en varias aplicaciones pequeñas en el pasado sin problemas inmediatos, pero sí logré problemas de escalabilidad en un par de aplicaciones cuando las aplicaciones crecieron en horas extras.

Qué patrón usar dependerá de las restricciones de envío y lo mejor que adivine acerca de la aplicación de evolución en todo su ciclo de vida. Si se trata de una pequeña aplicación, la aplicación delegada casi-singleton funcionará bien. Si la aplicación es más compleja, puede volverse más compleja o puede generar otras aplicaciones relacionadas que reutilizarán los componentes existentes, entonces la inyección de dependencia es el camino a seguir.

Cuestiones relacionadas