Кинжал синглтон против объекта Котлин - PullRequest
7 голосов
/ 23 мая 2019

Чтобы определить синглтон, я должен использовать объявление объекта kotlin или сделать обычный класс kotlin и внедрить его с помощью кинжала? По моему мнению, первый вариант определенно проще, но может быть причина использовать кинжал в этой ситуации, о которой я не знаю.

Вариант 1 (уведомление object ключевое слово):

object SomeUtil {
    fun someFunction(number: Long) {
        // ...
    }
}

Вариант 2 (уведомление class ключевое слово):

class SomeUtil {
    fun someFunction(number: Long) {
        // ...
    }
}
@Module
class AppModule {

    @Provides
    @Singleton
    internal fun provideTheUtil() = SomeUtil()
}
class MainActivity : BaseActivity() {

    @Inject internal lateinit var util: SomeUtil
}

ОБНОВЛЕНИЕ 2019-07-03

@ Блэкбелт сказал в комментариях, что мы должны предпочесть вариант 2 для тестируемости. Но библиотеки типа MockK могут mock object s тоже. Так вы все еще думаете, что вариант 2 является предпочтительным?

Ответы [ 3 ]

2 голосов
/ 03 июля 2019

Возможно, вы захотите пересмотреть вопрос о необходимости NumberFormatUtil быть одиночкой.Это может быть дешевле, если вы используете @Reusable с Dagger или даже фабрику без какой-либо области видимости напрямую.

Если NumberFormatUtil довольно прост и предоставляет только несколько служебных методов, нет состоянияи в тестах нет необходимости насмехаться, вы можете использовать реализацию object, возможно, @JvmStatic для Java -интерфейсности.Но тогда вы можете использовать и глобальные утилиты (расширения):

package xyz

fun formatNumber(number: Long) {
    // ...
}

fun Long.format() = formatNumber(this)
0 голосов
/ 17 июля 2019

Вы должны использовать опцию 2.

В разработке программного обеспечения одноэлементный шаблон является шаблоном проектирования программного обеспечения, который ограничивает создание экземпляра класса одним «единственным» экземпляром.Это полезно, когда ровно один объект необходим для координации действий в системе.

From: Singleton Pattern

Таким образом, singleton - это единственный экземпляр вобъем.В случае Android это экземпляр виртуальной машины, на котором запущено приложение.В случае, если вам нужны пользовательские области, вы должны использовать только вариант 2.

Но, если у вас есть только статические методы внутри объекта, вы хотите внедрить его, лучше сохранить их как глобальные методы и даже избавиться от object.Не нужно ничего вводить.Он похож на Java-класс только с статическими методами (я упоминал об этом, поскольку это обычный способ создания классов Utility).

Однако, если object также имеет некоторое состояние.Я бы порекомендовал идти по пути кинжала.Способ object не обеспечивает внедрение зависимостей.Это только создает синглтон.Ваша цель использования кинжала - внедрение зависимостей.

0 голосов
/ 15 июля 2019

Вы можете отлично делать инъекцию зависимостей без использования кинжала.Для этого есть множество фреймворков, но вы даже можете сделать это без фреймворка, делая все вручную.Вы можете (я сделал это) отлично написать приложение, используя методы DI, даже не используя каркас.

В kotlin вы можете прекрасно создать файл Utils.kt и вставить туда некоторые функции, ифункции будут доступны везде (также будет создан синглтон).

Мой совет: не усложняйте.

Если вы можете сделать это с чистым kotlin, и это не добавляет дополнительной сложности вашему приложению, то сделайте это.Если это затеняет или создаст беспорядок в вашей кодовой базе (или вы будете путать будущие кодеры, смешивая материалы и подходы), то не надо.

Дополнительно: Для объектов, когда вам необходимо напрямую контролироватьГрафик и т. д., есть много рамок на выбор.(Попробуйте Koin, действительно простой и друг Kotlin), вы можете использовать Dagger или некоторые из них, если ваше приложение действительно сложное.Но если вы можете позволить себе роскошь не использовать инфраструктуру DI и делать все самостоятельно, это будет намного лучше.

Я знаю, что не все согласятся с этой точкой зрения, но по моему опыту,Вот как это.

...