¿Elegir un Singleton o una categoría?

Bastante temprano en mi aplicación, cuando tenía mucha less experiencia que ahora, quería darle vida a algunas transiciones entre los controlleres de vista con mis propias animaciones personalizadas. Al no tener idea de por dónde empezar, miré alnetworkingedor de SO para ver un patrón como MVC al que se podía acceder desde casi cualquier controller en cualquier momento, y resulta que un singleton era el path a seguir.

Lo que no me di count es que parece haber un odio fuerte y bien defendido por el patrón único, y yo mismo estoy empezando a ver por qué, pero eso no viene al caso.

Entonces, un rato después, decidí mover mi misma implementación a una categoría en UINavigationController (después de todo, ¡maneja las transiciones!), Mantenía las classs originales para comparar y me preguntaba qué método funcionaría mejor. Después de haber probado a background ambas implementaciones, puedo decir sin lugar a dudas que son iguales en todos los sentidos, incluida la velocidad, precisión, suavidad, velocidad de fotogtwigs, uso de memory, etc., ¿cuál es "mejor" en el sentido de mantenibilidad general?

EDIT: después de leer los arguments bien escritos que todos ustedes han formulado, he decidido usar un singleton. @JustinXXVII ha hecho el argumento más convincente (en mi humilde opinión), aunque considero que todas las respuestas aquí merecen mérito. Gracias a todos por sus opiniones, he votado todas las respuestas en la pregunta.

Haré el caso para un object singleton. Singletons se utilizan en todo UIKit y iOS . Una cosa que no puede hacer con las categorías es agregar variables de instancia. Hay dos cosas al respecto:

  1. Los flujos de trabajo de MVC no toleran objects con conocimiento íntimo de otros objects.
  2. A veces solo necesitas un lugar para hacer reference a un object que realmente no pertenece a ningún otro lado

Estas cosas van en contra de otras, pero la capacidad adicional de poder mantener una variable de instancia que realmente no tiene un "propietario" es la razón por la que prefiero el singleton.

Normalmente tengo una class singleton en todos mis proyectos XCode, que se utiliza para almacenar objects "globales" y hacer cosas mundanas con las que no quiero cargar mi AppDelegate.

Un ejemplo sería serializar / archivar objects y desarchivar / restaurar. Tengo que usar el mismo método en varias classs, no quiero extender UIViewController con algún método de serialization para escribir y leer files arbitrarios. Tal vez es solo mi preference personal.

También podría necesitar una forma rápida de search información en NSUserDefaults, pero no quiero escribir siempre [[NSUserDefaults standardUserDefaults]stringForKey:@"blah"] , así que declararé un método en mi singleton que toma un argumento de cadena.

Hasta ahora, no he pensado demasiado en usar una categoría para estas cosas. Sin embargo, una cosa es segura: prefiero no crear un object nuevo cientos de veces para hacer la misma tarea cuando puedo tener solo un object vivo que se adhiera y se ocupará de mí. (Sin sobrecargar la AppDelegate)

Creo que la mejor opción es usar la categoría.

Porque si ya está utilizando UINavigationController, no tiene sentido crear una nueva class que solo gestione la transición, como usted dijo: (after all, it handles transitions!)

Esta será una mejor opción para mantener su código, y usted estará seguro de que lo hacen lo que esperan hacer, y si ya tiene una instancia que hace las transiciones, ¿por qué crear otra?

Los patrones de layout, como singleton, fábrica y otros, deben usarse con responsabilidad. En su caso, no veo por qué usar un singleton, lo usa solo para no crear instancias de objects nuevos, no necesita tener solo una instancia de él, pero lo hace porque desea uno solo.

En esta implementación, para la que no hay necesidad de usar Singleton, puede que no haya ninguna diferencia. Eso no significa que no haya uno.

Un cubo de plástico tiene tanta agua como un cubo de metal, y lo hace igual de bien. En ese aspecto, parece que no hay diferencia entre los dos. Sin embargo, si intenta transportar algo extremadamente caliente, el cubo de plástico podría no funcionar tan bien.

Lo que trato de decir es que ambos cumplen sus propósitos, pero en su caso no parecía haber ninguna diferencia porque la tarea era demasiado genérica. Quería un método que estuviera disponible en varias classs, y ambas soluciones pueden hacerlo.

En su caso, sin embargo, podría ser mucho más fácil usar una categoría. La implementación es más fácil y usted (posiblemente) necesita less código.

Pero si tuviera que crear un administrador de datos que contenga una serie de objects que SOLO desea disponibles en un solo lugar, una categoría no estará a la altura de la tarea. Esa es una tarea típica de Singleton. Singeltons son objects de instancia única (y, si se hacen estáticos, disponibles en casi todas partes). Las categorías son extensiones a sus classs existentes y limitadas a la class que se extiende.

Para responder tu pregunta; elige una categoría.

* Una subclass también puede funcionar, pero tiene sus propios pros y contras

¿Por qué no simplemente crea una subclass base UIViewController y extiende todos los controlleres de vista desde este object? Una categoría no tiene sentido para este propósito.

Creo que la verdadera pregunta está en el "layout" (como usted dijo, ambos códigos funcionan bien), y al escribir su problema en oraciones simples, encontrará su respuesta:

  • El propósito de Singleton es tener solo una instancia de una class en ejecución en su aplicación. Entonces puedes compartir cosas entre objects. (uno disponible para muchos objects)

  • La finalidad de la categoría es ampliar los methods disponibles para una class. (disponible solo para una class de objects! ok … objects de subclasss también)

lo que realmente desea es hacer una nueva transición disponible para la class UINavigationController. UINavigationController, que ya tiene algún método disponible para cambiar la vista (present modal view, addubviews, etc.) está diseñado para administrar vistas con transiciones (lo dijiste tú mismo, maneja las transiciones), todo lo que quieres hacer es agregar otra forma de manejo transiciones para sus controlleres de navigation, por lo que preferiría usar una categoría.

Mi opinión es que lo que quiere lograr está cubierto por la categoría y al hacerlo, se asegura de que los únicos objects que acceden a este método tengan derecho a usarlo. Con el patrón singleton, cualquier object de cualquier class podría llamar a su singleton y sus methods (y … podría funcionar a nadie sabiendo cómo para una versión del sistema operativo n, pero su aplicación podría romperse en la versión n + 1).

Singletons, como su nombre indica, debe usarse cuando existe la necesidad de ser exactamente un object en su aplicación. El patrón para el método de acceso garantiza que solo este requisito sea un método de class:

 + (MyClass*) shanetworkingInstance { static MyClass *instance = nil; if (instance == nil) instance = [[MyClass alloc] init]; return instance; } 

Si se implementa bien, la class también asegura que su constructor sea privado, por lo que nadie más puede instanciar la class, sino el método accessor: esto asegura que en cualquier momento como mucho exista una instancia de la class. El mejor ejemplo de dicha class es UIApplication ya que en cualquier momento puede haber solo un object de esta class.

El punto aquí es que este es el único requisito para Singleton. La function del método de acceso es garantizar que solo haya una instancia, y no que proporcione acceso a esa instancia desde cualquier lugar. Es solo un efecto secundario del patrón que, siendo el método de acceso estático, todos pueden acceder a este único object sin tener una reference (puntero) a él a priori. Lamentablemente, este hecho es ampliamente abusado por los progtwigdores del Objetivo C y esto lleva al layout desorderado y al odio hacia el patrón único que mencionaste. Pero, en general, no es culpa del patrón simple sino del mal uso de su método de acceso.

Ahora volviendo a su pregunta: si no necesita variables estáticas / globales en su código de transición personalizado (supongo que no), la respuesta es definitivamente search categorías. En C ++, subclasss de alguna class base BaseTransition e implementas tus methods de dibujo reales. El objective C tiene categorías (que, en mi opinión, son otra forma de desorderar el layout, pero son mucho más convenientes), donde puedes agregar funcionalidades personalizadas incluso accediendo a las variables de tu class de host. Utilícelos siempre que pueda canjear singletons con ellos y no use singletons cuando el requisito principal para su class no sea que sea solo una instancia de él.