Saltar al contenido →

Patrón Object Pool con Swift

Nueva entrega en la serie de artículos dedicados a los patrones de diseño de software. En este artículo veremos cómo implementar el patrón Object Pool con Swift.

Lo primero es explicar que el patrón Object Pool es una variación del patrón Singleton, y dicha variación consiste en que permite el acceso a múltiples instancias de un objeto en luga de a una sola.

Dichas instancias tienen la particularidad de que sólo pueden existir y usarse una vez el mismo tiempo.

¿Qué necesito para implementarlo?

Este patrón es de los que menos infraestructura requiere. Con una clase que haga las veces de contenedor de las distintas intancias de objetos nos vale.

Vamos a ver el Object Pool

Vamos a implementar un servicio de música alquiler de canciones. Nuestro servicio está empezando así que sólo tenemos una licencia de cada canción, por lo que sólo un usuario puede escuchar esa canción al mismo tiempo. Lo que también es limitado es nuestro repertorio, actualmente tenemos los derechos de 4 canciones.

El Object Pool – Primera aproximación

Lo que nuestra clase va a necesitar es una variable de tipo Array para almacenar los elementos y dos funciones, una para obtener un elemento del pool y otra para restaurarlo una vez el usuario haya terminado de usarlo.

Como vemos la implementación es muy sencilla. Quizá demasiado.

Si queremos usar nuestro Pool de objetos en un entorno concurrente con múltiples usuarios esta aproximación no nos vale, ya que no estamos controlando el acceso al Array que contiene nuestros objetos.

Para poder solucionarlo vamos a recurrir al framework Dispatch, más conocido por todos por GCD

El Object Pool – Ahora sí.

A la versión anterior le vamos a añádir una Queue se tipo secuencuial y un DispatchSemaphore que controle el número de instancias que hay disponibles en el pool y regule el acceso.

Si cuando creamos un DispatchQueue no usamos el parámetro attributtes se crea una cola de tipo serial en lugar de concurrent, que es lo más le conviene a nuestros intereses.

El DispatchSemaphore se inicializa con un valor igual al número de elementos que contiene el pool. De esta manera cuando se vaya reperar un elemento del pool se hace una llamada a su función wait() que espera hasta que el valor del semáforo sea distinto de 0, y si lo es le resta 1.

Cuando alguien devuelve un elemento al pool hacemos una llamada a la función signal() que aumenta en 1 el valor del semáforo.

Ahora todo junto

A continuación tenéis un ejemplo completo del uso del patrón Pool que se encarga de servidor las 4 canciones de nuestro servicio de streaming de música.

Tras ver nuestra capacidad los ingenieros de Apple Music y Spotify deben estar temblando… 😉

Conclusión

Object Pool es uno los patrones más fáciles de implementar que más utilidad tiene entre los distintos patrones.

Enlaces relacionados

Publicado en Patrones de Software Swift