Estoy lidiando con algunas situaciones de comunicación asíncrona (análisis XML basado en eventos, procesamiento de respuesta NSURLConnection, etc.). Trataré de explicar brevemente mi problema:Comunicación asincrónica Objective-c: patrón de objetivo/acción o delegación?
En mi situación actual, hay un proveedor de servicios (que puede hablar con un analizador xml o hacer algunas comunicaciones de red) y un cliente que puede solicitar al proveedor de servicios que realice de sus tareas asincrónicamente En este escenario, cuando el proveedor de servicios finaliza su procesamiento, debe comunicar los resultados al cliente.
Estoy tratando de encontrar un tipo de patrón o regla de oro para poner en práctica este tipo de cosas y veo 3 soluciones posibles:
1. Utilice el patrón delegación: el cliente es el proveedor de servicios de delegar y recibirá los resultados al completar la tarea.
2. Utilice un enfoque de objetivo/acción: El cliente le pide al proveedor de servicios que realice una tarea y pase un selector que deberá ser invocado por el proveedor de servicios una vez que haya finalizado la tarea.
3. Use las notificaciones.
( actualización) Después de un tiempo de tratar la solución # 2 (objetivo y acciones), que llegó a la conclusión de que, en mi caso, es mejor usar el enfoque de delegación (# 1). Aquí están los pros y los contras de cada opción, tal como los veo: enfoque
Delegación:
1 (+) La ventaja de la opción 1 es que podemos cheque de compilación -time errors porque el cliente debe implementar el protocolo delegado del proveedor de servicios.
1 (-) Esto también es un inconveniente porque hace que el cliente se acople estrechamente con el proveedor de servicios ya que tiene que implementar su protocolo de delegado.
1 (+) Permite al programador navegar fácilmente por el código y encontrar qué método del cliente, el proveedor del servicio está invocando para pasar sus resultados.
1 (-) Desde el punto de vista del cliente, no es tan fácil encontrar qué método será invocado por el proveedor del servicio una vez que tenga los resultados. Todavía es fácil, solo diríjase a los métodos de protocolo de delegados y eso es todo, pero el enfoque n. ° 2 es más directo.
1 (-) Tenemos que escribir más código: defina el protocolo de delegado e impleméntelo.
1 (-) Además, el patrón de delegación se debe utilizar, de hecho, para delegar el comportamiento. Este escenario no sería un caso exacto de delegación, semánticamente hablando.
Acción/Approach Target
2 (+) La ventaja de la opción 2 es que cuando se está llamando el método de proveedor de servicios, el @selector especificando la acción devolución de llamada debe también se especificará, por lo que el programador sabe exactamente qué método se invocará de nuevo para procesar los resultados.
2 (-) En oposición a esto, es difícil encontrar qué método volverá a llamarse en el cliente mientras navega por el código del proveedor de servicios. El programador debe ir a la invocación del servicio y ver qué @selector se está transfiriendo.
2 (+) Es una solución más dinámica y causa menos acoplamiento entre las piezas.
2 (-) Tal vez una de las cosas más importantes: Puede causar errores en tiempo de ejecución y los efectos secundarios, ya que el cliente puede pasar a un selector que no existe para el proveedor de servicios.
2 (-) Utilizando el enfoque simple y estándar (#performSelector: withArgument: withArgument :) el proveedor de servicio sólo puede pasar hasta 2 argumentos.
Notificaciones:
- no elegiría notificaciones porque creo que se supone que se utilizará cuando más de un objeto necesitan ser actualizados. Además, en esta situación, me gustaría decirle directamente al delegado/objeto de destino qué hacer después de generar los resultados.
Conclusión: En este punto, elegiría el mecanismo de delegación. Este enfoque proporciona más seguridad y permite navegar fácilmente por el código para seguir las consecuencias de enviar al delegado los resultados de las acciones del proveedor del servicio. Los aspectos negativos de esta solución son que: es una solución más estática, necesitamos escribir más código (relacionado con el protocolo) y, semánticamente hablando, no estamos hablando realmente de delegación porque el proveedor de servicios no estaría delegando nada .
¿Echo de menos algo? ¿Qué recomiendas y por qué?
Gracias!
Gracias Mihirsm, Tiene razón, eso evitará un error en tiempo de ejecución. Pero aún así, el hecho de que el programador usara un selector incorrecto no será visible hasta el tiempo de ejecución. Eso podría crear efectos secundarios: S. Nuevamente, una ventaja para el mecanismo de delegación más estático pero seguro. ¡Salud! – Lio
Puede hacer que esto sea un poco más seguro implementando @protocol y haciendo que el delegado cumpla con este protocolo. Esto asegurará que la clase de delegado implemente los métodos requeridos. También puede agregar una aserción en su método setDelegate: para probar que el nuevo objeto se ajusta al protocolo. –
La forma predeterminada para los métodos declarados en protocolos es que sean '@ optional', por lo que' [delegate respondsToSelector: callback] 'sigue siendo necesario. Puedes usar '@ required' en tu protocolo, pero he descubierto que la mayoría de las personas no lo hacen. Mi solución fue crear un trampolín 'NSProxy' devuelto por una extensión' NSObject', '- [NSObject ifResponds]'. Solo azúcar sintáctico que te permite no tener todas esas tonterías 'si'. –