“Delegation” en Swift

A lo largo de tu carrera como desarrollador de aplicaciones para iOS te encontrarás utilizando muchos patrones de diseño como por ejemplo Singleton, MVC, Decorator, Observer; pero uno de los más importantes y utilizados es Delegation. Antes de entrar en detalles, ¿qué es un patrón de diseño?

Patrones de diseño

No vamos a profundizar en este post acerca de los patrones de diseño pues hay muchos artículos y libros sobre el tema, solamente veremos de que se trata y pueden consultar luego al respecto.

El concepto de patrones de diseño fue introducido en 1994 en el libro “Design Patterns: Elements of Reusable Object-Oriented Software” de los autores Erich Gamma, Ralph Johnson, Richard Helm, John Vlissides, el cual trata sobre temas de Programación Orientada a Objetos y patrones de diseño y desde entonces ha influenciado mucho en la ingeniería de software; este colectivo de autores es conocido por “Gang of Four (GoF)”.

Los patrones de diseño representan buenas prácticas utilizadas por desarrolladores de software, soluciones generales a problemas que se presentan durante el desarrollo de software. Estas soluciones fueron obtenidas mediante un proceso de ensayo y rectificación de errores de muchos desarrolladores de software a lo largo de un período considerable de tiempo.

Delegation

Este patrón brinda la posibilidad a una clase o estructura de entregar (o delegar) alguna de sus responsabilidades a una instacia de otro tipo.

La implementación de este patrón esta basada en la definición de un protocolo que encapsule las responsabilidades que serán delegadas de modo tal que se garantiza que el tipo que implemente este protocolo (conocido como delegado) proveerá las funcionalidades que han sido delegadas.

Veamos un ejemplo en la próxima sección.

Implementando el patrón

Vamos a utilizar como ejemplo la implementación sencilla de una clase CuentaDeAhorros la cual va a permitir a sus usuarios modificar su saldo.

Como pueden ver es una clase muy sencilla, la cual solo tiene una propiedad saldo, con lo cual es suficiente para el ejemplo que queremos mostrar, en una aplicación real probablemente saldo sería un atributo privado y tendríamos métodos para extraer dinero, depositar dinero, etc.

Si queremos crear una cuenta de ahorros y ponerle como saldo $5 solo tenemos que hacer lo siguiente:

Queremos adicionar una nueva funcionalidad la cual consiste en poder notificar cuando se detecte un cambio en una cuenta de ahorros y para ello vamos a utilizar la delegación de modo que la clase CuentaDeAhorros delegue esa responsabilidad.

Primeramente definamos el protocolo que va a encapsular las responsabilidades a delegar, la cual sería “notificar cualquier cambio de saldo que ocurra en la cuenta”:

Al protocolo lo llamaremos CuentaDeAhorrosDelegate porque son responsabilidades de la cuenta de ahorros que queremos delegar y queremos agruparlas de modo que el delegado pueda implementarlas a través de este protocolo.

Es importante destacar que en un protocolo deben estar definidos métodos, propiedades, etc. que respondan a una misma tarea, en este ejemplo solo tendremos un método para notificar cambios en el saldo de la cuenta, si mañana queremos adicionar otro método relacionado con cambios en el saldo de la cuenta podemos ponerlo en este protocolo pero si en cambio, queremos adicionar un método que tenga que ver con otra tarea, es recomendado definir otro protocolo.

Es hora de definir nuestro delegado, el cual va a implementar el protocolo CuentaDeAhorrosDelegate:

  1. Definimos una clase llamada Notificador pues su tarea será notificar los cambios de saldos.
  2. La hacemos implementar el protocolo CuentaDeAhorrosDelegate.
  3. Colocamos la implementación del método func notificarCambioDeSaldo(saldoActual: Double, nuevoSaldo: Double). En este caso lo que va a hacer este método es imprimir cuál es el saldo actual y cuál va a ser el nuevo saldo. En una aplicación real posiblemente queremos registrar esto en una base de datos, en un archivo, etc.

El próximo paso es modificar la clase CuentaDeAhorros para que utilice al delegado para delegar la funcionalidad de notificar cuando se realice un cambio en el saldo de la cuenta. Entonces realizamos las siguiente modificaciones:

Las modificaciones realizadas fueron las siguientes:

  1. Adicionamos un nueva propiedad llamada delegate que es de tipo CuentaDeAhorrosDelegate el cual es el protocolo que definimos para representar las tareas a delegar; utilizamos el protocolo y no directamente el tipo Notificador porque de ese modo podemos utilizar cualquier tipo que en el futuro implemente  CuentaDeAhorrosDelegate, en otras palabras podemos decir que a través de la propiedad delegate vamos a inyectar a nuestro delegado.
  2. Modificamos la implementación de la propiedad saldo para adicionar un observador, los observadores de propiedades (property observers) es una funcionalidad de Swift para las propiedades, estos observadores observan y responden a cambios en los valores de las propiedades, pueden ver más en la documentación de Apple. Para este caso vamos a utilizar willSet el cual nos va a notificar cuando vaya a ocurrir un cambio en el valor de la propiedad antes de que ocurra y además permite el uso de un argumento donde viene el futuro valor de la propiedad, en este caso nuevoSaldo.
  3. Finalmente, en la implementación del observador, llamamos al método notificarCambioDeSaldo de nuestro delegado pasándole el saldo actual y el nuevo saldo.

Lo último que falta es registrar un delegado a nuestra instancia de CuentaDeAhorros, y lo podemos hacer de la siguiente manera:

  1. Primeramente creamos una instancia de Notificador llamada notificador.
  2. Creamos nuestra instancia de CuentaDeAhorros llamada cuenta.
  3. “Inyectamos” nuestro delegado notificador en nuestra instancia de CuentaDeAhorros a través de su propiedad delegate.
  4. En la cuarta línea cambiamos el saldo y le asignamos 5, al hacer esto se va a ejecutar el observador de saldo willSet y va a llamar al método notificarCambioDeSaldo en nuestro delegado, como nuestro delegado es notificador que es de tipo Notificador, lo que va a suceder es que se va a imprimir el siguiente texto “El saldo actual es $0.0 y el nuevo saldo será $5.0\n”.
  5. En la quita línea volvemos a cambiar el saldo, esta vez a 20 y va a suceder lo mismo pero en esta ocasión como el saldo actual era 5, el texto que se va a imprimir es “El saldo actual es $5.0 y el nuevo saldo será $20.0\n”.

Como decíamos al principio, es importante aprender como funciona este patrón pues en el desarrollo de aplicaciones para iOS se encontrarán implementando y utilizando este patrón una y otra vez.

4 comentarios en ““Delegation” en Swift

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s