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

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

NULL 对象在 Kotlin 中有效吗?

尽管 Kotlin 允许在构造函数中添加默认值,但是否有理由不鼓励使用 NULL 对象,就像上面的代码片段一样?

假设我不需要只使用一个参数来构造对象,例如:Foo("ABC") 或 Foo(5)。(...在修改 Foo 以在构造函数中具有默认值之后)

https://sourcemaking.com/design_patterns/null_object

4

3 回答 3

2

Singleton 不是你所拥有的合适的词。单例是只允许一个实例的类。这只是一个可以具有许多实例的类的全局可访问实例。

我建议不要调用它,NULL因为在 Kotlin 中 null 这个词的含义。可能相当具有误导性。也许叫它EMPTY

这是否是一种不好的做法将取决于您如何使用它,但是保留一些长期存在的类实例并没有本质上的错误。

但是,我会避免使用这样的可变类来执行此操作。这暗示它是一个常数,但在您的示例中,有人可以NULL.param2从应用程序中的任何位置更改 的值,并在其他地方破坏依赖于其值为 0 的代码。

于 2020-02-07T04:40:43.023 回答
1

空对象是有效的 Kotlin 设计模式。

当您使用此模式时,您应该创建一个接口并让常规类和空对象都实现它。此外,null 对象应该像所有其他单例一样是不可变的。

以下是在 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
于 2020-02-07T15:58:56.200 回答
0

您可以创建一个不带参数的工厂函数,该函数将返回一个空对象:

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

private val nullFoo = Foo("", 0)

fun Foo() = nullFoo
于 2020-02-06T23:01:09.480 回答