Los objects en Kotlin: Crea singletons seguros en una línea (KDA 27)
Antonio Leiva

Los objects de Kotlin son otro de los elementos del lenguaje al que no estamos acostumbrados los desarrolladores en Android, porque no hay nada parecido en Java.

En realidad un object no es más que un tipo de datos con una única implementación. Por lo que si queremos sacarle algún parecido, éste sería el patrón Singleton de Java. En un momento los compararemos.

Si quieres aprender cuál es la situación de Kotlin en el mercado, por qué debes aprenderlo y los primeros pasos para que veas lo fácil que es, he preparado un training gratuito de hora y media al que puedes unirte haciendo click aquí.

Singleton vs object

El singleton en Java no es tan fácil de implementar como parece. Uno podría pensar que es tan sencillo como esto:

public class Singleton {

    private Singleton() {
    }

    private static Singleton instance;

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }

        return instance;
    }
}

Pero este código es peligroso, sobre todo si se utiliza en distintos hilos. Si dos hilos acceden a la vez a este singleton, se podrían generar dos instancias de este objeto. Un código más correcto sería:

public class Singleton {

    private static Singleton instance = null;

    private Singleton(){
    }

    private synchronized static void createInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
    }

    public static Singleton getInstance() {
        if (instance == null) createInstance();
        return instance;
    }
}

Como ves, necesitas unas cuantas líneas para crear un Singleton válido.

¿Cuál sería el equivalente en Kotlin?

object Singleton

No necesitas más.

Declaración de objetos

Declarar un objeto es tan sencillo como declarar una clase. La nomenclatura es la misma.

Vamos a declarar por ejemplo un objeto que implemente un helper de base de datos:

object MySQLOpenHandler : SQLiteOpenHelper(App.instance, "MyDB", null, 1) {
    
    override fun onCreate(db: SQLiteDatabase?) {
    }

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
    }

}

El objeto se instancia la primera vez que se llama.

Companion Object

Toda clase puede tener un companion object, que es un objeto que es común a todas las instancias de esa clase. Vendría a ser similar a los campos estáticos en Java.

Un ejemplo de implementación:

class App : Application() {
    companion object {
        lateinit var instance: App
            private set
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
    }

}

En este caso estoy creando una clase que extiende de Application y que almacena en el companion object su única instancia.

El lateinit indica que esa propiedad no va a tener valor desde el principio, pero que se hará antes de que se use (en otro caso lanzará una excepción).

El private set se usa para que no se pueda asignar un valor desde otra clase que no sea esta.

Nota: Puedes pensar que tendría bastante sentido que App fuera un object en vez de una clase. Y así es, pero debido a la forma que el framework de Android tiene de instanciar las clases, si lo intentas verás que la aplicación lanza una excepción nada más lanzarse. Necesitarás que App sea una clase, y crearte este pequeño Singleton si quieres acceder a ella.

Expresiones object

Los objects también se pueden utilizar para crear implementaciones anónimas de clases.

Un ejemplo:

recycler.adapter = object : RecyclerView.Adapter() {
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder?, position: Int) {
    }

    override fun getItemCount(): Int {
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): RecyclerView.ViewHolder {
    }

}

Pero un object también puede representar una clase que no existe. Puedes crearla al vuelo:

val newObj = object {
    var x = "a"
    var y = "b"
}

Log.d(tag, "x:${newObj.x}, y:${newObj.y}")

Conclusión

Los objects son un concepto nuevo para los que venimos de Java 6, pero hay muchas ideas que se pueden asociar con otras ya existentes, así que te harás rápido con ellos.

Si te gusta lo que has visto, te animo a que te apuntes al training gratuito, donde te contaré todo lo que necesitas para aprender a crear tus Apps Android en Kotlin desde cero.

Quizá también te interese…

¿Qué es Kotlin Multiplataforma?

¿Qué es Kotlin Multiplataforma?

En el mundo actual, donde los dispositivos móviles están presentes en nuestra vida diaria, es fundamental para los desarrolladores crear aplicaciones que se adapten a diferentes sistemas operativos. Kotlin Multiplataforma es una herramienta que facilita la creación de...

5 trucos de Kotlin para escribir código más eficiente en Android

5 trucos de Kotlin para escribir código más eficiente en Android

El lenguaje de programación Kotlin se ha convertido en el más popular para el desarrollo de aplicaciones de Android en los últimos años. Su sintaxis concisa y moderna, junto con su capacidad para mejorar la eficiencia de código, lo convierten en una opción atractiva...

Cómo crear un backend en Kotlin usando Ktor

Cómo crear un backend en Kotlin usando Ktor

Ktor es un framework de servidor web ligero y rápido para Kotlin, desarrollado por JetBrains. Es ideal para crear aplicaciones web y servicios RESTful, y es muy fácil de usar y configurar. En este artículo, vamos a ver cómo crear un backend para una aplicación de...

2 Comentarios

  1. Oscar

    Excelente trabajo, entendí bien.

    Responder

Enviar un comentario

Los datos personales que proporciones a través de este formulario quedarán registrados en un fichero de DevExpert, S.L.U., con el fin de gestionar los comentarios que realizas en este blog. La legitimación se realiza a través del consentimiento de la parte interesada. Si no se acepta, no podrás comentar en este blog. Los datos que proporciona solo se utilizan para evitar el correo no deseado y no se usarán para nada más. Puede ejercer los derechos de acceso, rectificación, cancelación y oposición en contacto@devexperto.com.

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Acepto la política de privacidad *