Search code examples
kotlinfactory-patterncompanion-object

Creating a DB factory using kotlin


So I'm trying to create a MongoDB factory with kotlin... but I think I don't really understand the concept of companion object very well because I can't even get this to compile:

package org.jgmanzano.storage

import com.mongodb.MongoClient
import com.mongodb.MongoClientURI
import com.mongodb.client.MongoDatabase

class MongoConnectionFactory(private val connectionURI: String) {
    private var database: MongoDatabase

    init {
        val connectionString = MongoClientURI(connectionURI)
        val mongoClient = MongoClient(connectionString)
        database = mongoClient.getDatabase("paybotDB")
    }

    companion object {
        fun getDatabase() : MongoDatabase {
            return database
        }
    }
}

How would you guys achieve this? My idea is to create what in Java would be a kind of factory method. I can't seem to get the syntax right tho.

Furthermore, would this be a correct approach to DB connection factories?


Solution

  • Move everything to the companion object, pass the connection URI to the getDatabase method. Companion objects get compiled as a static field inside the containing (outer class). Since the field is static, it cannot access outer class's fields because the outer class is an instance.

    I assume you want to cache database objects.

    class MongoConnectionFactory() {
    
        companion object {
            private var database: MongoDatabae? = null
    
            fun getDatabase(connectionURI: String) : MongoDatabase {
                if (database != null) {
                    return database
                {
                val connectionString = MongoClientURI(connectionURI)
                val mongoClient = MongoClient(connectionString)
                database = mongoClient.getDatabase("paybotDB")
                return database
            }
        }
    }
    

    But then you don't need a companion object nested inside containing class. You can create an object instead.

    object MongoConnectionFactory {
        private var database: MongoDatabae? = null
    
        fun getDatabase(connectionURI: String) : MongoDatabase {
            if (database != null) {
                return database
            {
            val connectionString = MongoClientURI(connectionURI)
            val mongoClient = MongoClient(connectionString)
            database = mongoClient.getDatabase("paybotDB")
            return database
        }
    }
    

    If you need multiple databases with different connection URIs then store them inside the hash table.