【问题标题】:Kotlin- Single instance of a non-singleton class?Kotlin-非单例类的单个实例?
【发布时间】:2015-11-17 01:47:55
【问题描述】:

我正在使用 Kotlin 进行一些实验,并且正在使用单例模式。我想保留 Database 对象的单个实例。就像在 Java 中一样,我想我会在它周围包裹一个单例。

import com.github.davidmoten.rx.jdbc.ConnectionProviderFromUrl
import com.github.davidmoten.rx.jdbc.Database

object DbManager {
    val database : Database =
            Database.from(ConnectionProviderFromUrl("jdbc:sqlite:C:/Users/Thomas/OneDrive/Data/finance_rx.db").get())
}

然而,令我惊讶的是似乎没有内置的方法来为它编译 getter(比如类的属性)。它只是直接将database 属性暴露给世界,没有任何封装,这是我不想要的。

我可以将其设为私有并明确地创建自己的 getter(但我正在关注 Kotlin,因为我热衷于懒惰)。但是,我想我偶然发现了另一种方法来做到这一点。

我可以创建一个 Kotlin 文件并声明一个私有变量和一个公共函数来安全地封装和公开它,而根本不需要将它放在任何类或单例中!

import com.github.davidmoten.rx.jdbc.ConnectionProviderFromUrl
import com.github.davidmoten.rx.jdbc.Database

private val database : Database =
        Database.from(ConnectionProviderFromUrl("jdbc:sqlite:C:/Users/Thomas/OneDrive/Data/finance_rx.db").get())

fun db(): Database = database;

问题是感觉太容易了。我觉得我在做坏事。但与此同时,这是有道理的。没有人喜欢给MySingleton.getInstance().getDb() 打一百次电话。我发现的这种模式是有效的而不是反模式吗?

另外,有没有办法编译 getter 并将最终属性封装在单例上?还是我自己实现这些方法?

【问题讨论】:

    标签: kotlin


    【解决方案1】:

    我发现的这个模式是有效的而不是反模式吗?

    是的,这是一个有效的模式

    另外,有没有办法编译 getter 并将最终属性封装在单例上?还是我自己实现这些方法?

    Kotlin 属性不仅仅是字段:它们已经为它们生成了 getter,因此拥有 databasedb() 并不比只有 database 更好。

    如果您以后需要在不重新编译客户端的情况下更改属性的行为,可以编写自定义 getter:

    val database: Database
        get() = ...
    

    这只会改变 getter 的主体,否则会自动为您生成

    【讨论】:

    • 非常感谢 Andrey,我很困惑,因为我正在从 Java 代码访问 Kotlin 类(它显示了用于互操作性的显式 getter)。在直接 Kotlin 中访问它时,我期待它是同样的事情。我现在明白了,它就像 C#。
    • 顺便说一句,再次感谢您将这门伟大的语言放在一起。这就是我希望 Java 成为的一切以及更多(尤其是来自 C# 作为我的第一语言)。
    猜你喜欢
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多