كيف يمكنني أن أجعل هذا المفرد أبسط في Kotlin؟

2

كيف يمكنني جعل هذا المفرد أكثر بساطة في Kotlin لتهيئة قاعدة بيانات غرفة Android؟

@Database(entities = arrayOf(Book::class, User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {

    abstract fun bookModel() : BookDao
    abstract fun userModel() : UserDao

    companion object {
        private var INSTANCE: AppDatabase? = null

        fun getInMemoryDatabase(context: Context): AppDatabase {
            if (INSTANCE == null) {
                INSTANCE = Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
            }
            return INSTANCE!!
        }

        fun destroyInstance() {
            INSTANCE = null
        }
    }
}

3 الاجابة

2
افضل جواب

يمكنك استخدام مصفوفة حرفية ( [] ) بدلا من arrayOf ويمكنك استخدام عامل الفيس لإجراء الفحص الفارغ. انظر هنا .

@Database(entities = [Book::class, User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {

    abstract fun bookModel() : BookDao
    abstract fun userModel() : UserDao

    companion object {
        private var INSTANCE: AppDatabase? = null

        fun getInMemoryDatabase(context: Context) { 
            INSTANCE = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
            return INSTANCE!!
        }

        fun destroyInstance() {
            INSTANCE = null
        }
    }
}

نظرًا لأنك تحتاج إلى المثيل ، يجب عليك حفظه في مكان ما ، باستخدام ملف companion object يبدو لي كحل معقول.

إذا كنت لا تريد بطريقة ما حفظ intence في الداخل AppDatabase ، يمكنك أيضًا استخدام كائن (وهو مفرد في Kotlin).

object AppDatabaseProvider {
    private var INSTANCE: AppDatabase? = null

    fun getInMemoryDatabase(context: Context) {
       // ...
    }

    fun destroyInstance() {
        INSTANCE = null
    }
}

هذان خياران للتعامل مع البيانات الثابتة في Kotlin ، لكنك لن تقصرها كثيرًا على ذلك.

:مؤلف
1
افضل جواب

الحل الخاص بك على ما يرام كما هو.

يعد استخدام مصفوفة حرفية خيارًا ، كما تمت الإشارة إليه بواسطةWilli Mentzel ، فهو يجعل شفرتك أقصر قليلاً ، إذا كنت تحب كيف تبدو.

ومع ذلك ، فإن هذا الرمز للحصول على مثيل singleton خاطئ:

private var INSTANCE: AppDatabase? = null

fun getInMemoryDatabase(context: Context) = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()

ال getInMemoryDatabase لا تقوم الدالة بتخصيص قيمة لـ INSTANCE ، بمعنى أنه سيكون إلى الأبد null وفي كل مرة يتم استدعاء الوظيفة ، سيتم تقييم الجانب الأيمن لعامل Elvis وإعادته. هذا يعني حالة جديدة في كل مرة - بدلاً من أن يكون لديك قائمة فردية ، فأنت تقوم فقط بإنشاء مصنع باستخدام هذا الرمز.


هل يمكن استخدام المشغل ألفيس لتقصير الأصلي الخاص بك كود قليلا:

fun getInMemoryDatabase(context: Context): AppDatabase {
    INSTANCE = INSTANCE ?: Room.inMemoryDatabaseBuilder(context.applicationContext, AppDatabase::class.java).build()
    return INSTANCE!!
}

سيؤدي هذا مهمة إضافية لـ INSTANCE على الرغم من كل مكالمة بعد المكالمة الأولى ، وأود أن أزعم أن حفظ هذين الخطين قد لا يستحق ذلك ، لأن كودك الأصلي مع فحص فارغ عادي كان أسهل في القراءة من هذا.

:مؤلف
0

ربما سيكون أي تقدم ، حاول على النحو التالي

@Database(entities = arrayOf(Book::class, User::class), version = 1)
abstract class AppDatabase : RoomDatabase() {

    abstract fun bookModel() : BookDao
    abstract fun userModel() : UserDao

    companion object {
        private var INSTANCE: AppDatabase? = null

        fun getInMemoryDatabase(context: Context): AppDatabase {
            return INSTANCE :? Room.inMemoryDatabaseBuilder(context, this).build()
        }

        fun destroyInstance() {
            INSTANCE = null
        }
    }
}
:مؤلف
فوق
قائمة طعام