我正在用 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())
}
然而令我惊讶的是,似乎没有内置的方法来编译它的 getters(比如类的属性)。它只是直接将数据库属性暴露给世界,没有任何封装,这是我不想要的。
我可以将其设为私有(private)并显式地创建我自己的 setter/getter (但我正在考虑 Kotlin,因为我热衷于偷懒)。然而,我想我偶然发现了另一种方法来做到这一点。
我可以创建一个 Kotlin 文件并声明一个私有(private)变量和一个公共(public)函数来安全地封装和公开它,而无需将其放入任何类或单例中!
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 并在单例上封装最终属性?或者我自己实现这些方法?
最佳答案
Is this pattern I discovered valid and not an anti-pattern?
是的,这是一个有效的模式
Also, is there any way to compile getters and encapsulate final properties on the singleton? Or do I implement those methods myself?
Kotlin 属性不仅仅是字段:它们已经生成了 getter,因此具有 database
和db()
并不比 database
更好.
如果您稍后需要更改属性的行为而不重新编译客户端,则可以编写自定义 getter:
val database: Database
get() = ...
这只会更改 getter 的主体,否则会自动为您生成
关于Kotlin-非单例类的单个实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33747805/