Del curso: Desarrollo Android: Arquitectura avanzado

El patrón Singleton

Un Singleton es un tipo que nos asegura que habrá una única instancia del mismo en nuestro sistema y que se inicializa en su primer uso. A pesar de que en ocasiones es considerado un antipatrón cuando se abusa de él, a veces nos será muy útil. Podría sernos útil, por ejemplo, para crear un repositorio que nos asegure una única fuente de verdad en toda la aplicación. El hacerlo en Java requiere de una cierta experiencia, pues podemos enfrentarnos a condiciones de carrera en entornos concurrentes. Sin embargo, Kotlin nos lo pone muy fácil con su definición de object. Veamos. La declaración de un object es similar a la de una clase. Hacemos New > Kotlin class, y seleccionamos Object, y le voy a llamar «MiSingleton». En lugar de usar la palabra class, usamos la palabra object para declararlo. Podemos tener propiedades. Por ejemplo, «ancho» de tipo «Int» que comienza con el valor «260» y «alto» de tipo «Int» que comience con el valor «420». También podemos tener métodos, «fun obtenerArea = ancho * alto». Y podemos tener bloques init, «init» y mostramos por pantalla «"Inicializando MiSingleton"». Lo que no podemos tener son constructores, y esto a veces es un inconveniente por ejemplo cuando necesitamos que nuestro Singleton tenga acceso al contexto de la aplicación. Esto lo podemos solventar creando una clase que extienda de Application para nuestro proyecto y a la que se pueda consultar el contexto. O podemos crear un método de inicialización para nuestro Singleton. Si necesitamos un contexto, podemos crear la función «inicializar» a la que se lo pasemos y hacemos «this.context = context». Debemos tener cuidado de guardar el contexto perteneciente a la aplicación y no a una activity en concreto, ya que al ser el Singleton compartido por toda la aplicación puede estar usando un contexto que ya no existe. Entonces haremos «context.applicationContext». Otra cosa que pueden hacer nuestros Singleton es que pueden extender otras clases o implementar interfaces. Por ejemplo, si tenemos la interfaz, New, selecciono interfaz y le llamo «MiInterfaz», con dos métodos «fun1» y «fun2», si hago que mi Singleton la implemente, ocurriría exactamente igual que en una clase. Cuando queramos usar nuestro Singleton, accederemos a él a través de su nombre. Podemos acceder a sus propiedades y también a sus funciones. «"El área es MiSingleton.obtenerArea"». Vamos a ejecutar nuestro programa para ver qué se muestra por Logcat. Y aquí tenemos la ejecución del bloque init. Esta ejecución ocurrirá solamente una vez en cada ejecución de nuestra aplicación, y en este caso ha ocurrido al asignarle un valor a la propiedad alto. Además, este valor será el que vean todas nuestras clases que accedan al Singleton, ya que es una instancia compartida. Como ves, los object de Kotlin nos lo ponen muy fácil a la hora de implementar nuestros Singleton. La mayor desventaja es que no tienen un constructor y por lo tanto no podremos inyectarles así ninguna dependencia, pero hay varias formas de solventarlo.

Contenido