Почему бы не реализовать шаблон синглтона для объекта NULL в Kotlin? - PullRequest
0 голосов
/ 07 февраля 2020
class Foo(val param1: String, var param2: Int) {
        // class body

        companion object {
                val NULL = Foo("", 0)
        }
}

Является ли объект NULL действительным в Kotlin?

Хотя Kotlin позволяет добавлять значения по умолчанию в конструкторе, есть ли причина для отказа от объекта NULL, как в приведенном выше фрагменте ?

Допустим, мне не нужно разрешать создание объектов только с одним параметром, например: Foo ("AB C") или Foo (5). (... после изменения Foo, чтобы в конструкторе были значения по умолчанию)

https://sourcemaking.com/design_patterns/null_object

Ответы [ 3 ]

2 голосов
/ 07 февраля 2020

Синглтон - не то слово, которое у вас есть. Singleton - это класс, в котором разрешен только один экземпляр. Это просто глобально доступный экземпляр класса, который может иметь много экземпляров.

Я бы посоветовал не называть его NULL из-за значения слова null в Kotlin. Может быть довольно обманчиво. Возможно, назовите это EMPTY.

Будет ли это плохая практика, будет зависеть от того, как вы ее используете, но нет ничего изначально неправильного в сохранении некоторых долгоживущих экземпляров классов.

Однако я бы избегал делать это с изменяемым классом, подобным этому. Подразумевается, что это константа, но в вашем примере кто-то может изменить значение NULL.param2 из любого места в приложении и нарушить код в другом месте, где его значение равно 0.

0 голосов
/ 07 февраля 2020

Нулевой объект является допустимым Kotlin шаблоном проектирования.

Когда вы используете этот шаблон, вы должны создать интерфейс и заставить его реализовывать как обычный класс (ы), так и нулевой объект. Кроме того, нулевой объект должен быть неизменным, как и все другие синглтоны.

Вот как вы можете реализовать шаблон проектирования пустых объектов в Kotlin:

interface Foo {
    val param1: String
    val param2: Int
}

object NullFoo : Foo {
    override val param1: String get() = ""
    override val param2: Int get() = 0
}

class FooImpl(override val param1: String, override var param2: Int) : Foo

В качестве альтернативы, вы можете использовать действительные значения null и функции расширения (свойства) с обнуляемыми приемниками:

class Foo(val param1: String, var param2: Int)

val Foo?.param1: String get() = this?.param1 ?: ""
val Foo?.param2: Int get() = this?.param2 ?: 0
0 голосов
/ 07 февраля 2020

Вы можете создать фабричную функцию без параметров, которая будет возвращать нулевой объект:

class Foo(val param1: String, var param2: Int) {
        // class body
}

private val nullFoo = Foo("", 0)

fun Foo() = nullFoo
...