在Kotlin中,不像Java有静态变量和静态方法,那么如何实现单例模式呢?在这片文章中将介绍在Kotlin中如何实现单例模式
单例模式(Singleton Pattern)是最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
1、单例类只能有一个实例。2、单例类必须自己创建自己的唯一实例。3、单例类必须给所有其他对象提供这一实例。在Kotlin中,没有静态变量和静态方法,但是可以通过Kotlin中的 伴生对象 来实现(关于伴生对象可参考Kotlin学习笔记——对象表达式与对象声明中关于伴生对象的相关介绍)。下面,我们用懒汉式的单例模式实现作为示例:
懒汉式单例模式 fun main(args: Array<String>) { Singleton.getInstance().code = 200 Singleton.getInstance().msg = "Success" Singleton.getInstance().data = "Data" Singleton.getInstance().print() // 通过多次打印获取到的单例,验证都是同一个对象 println(Singleton.getInstance()) println(Singleton.getInstance()) println(Singleton.getInstance()) } class Singleton private constructor(){ // 单例,私有的主构造函数,无从构造函数 var code: Int = 0 var msg: String = "" var data: String = "" // 声明类的伴生对象 companion object { private var singleInstance: Singleton? = null get() { // 懒汉模式 if(null == field) { field = Singleton() } return field } @Synchronized // 添加注解,线程同步,线程安全 fun getInstance(): Singleton { return singleInstance!! // 表示非空时执行 } } fun print() { println("Result: $code, $msg, $data") } }以上示例中,如果将伴生对象的属性声明为开放,那么Singleton类是可以忽略伴生对象名称(以上示例伴生对象名称省略掉)直接调用伴生对象的属性,之所以在伴生对象内部增加了getInstance()函数,是因为 懒汉式 的单例模式,单例对象初始值是null,在getInstance()函数里返回单例对象时增加一个非空断言(!!),这样就无需再每个调用的地方都增加非空断言。如果使用 饿汉式 的单例,可以完全不经过伴生对象内部的函数来中转(只需要将伴生对象的单例对象声明为开放,当然,如果为了保持队形,你依旧可以在伴生对象中声明个函数进行中转)
饿汉式单例模式 fun main(args: Array<String>) { Singleton.instance.code = 200 Singleton.instance.msg = "Success" Singleton.instance.data = "Data" Singleton.instance.print() // 通过多次打印获取到的单例,验证都是同一个对象 println(Singleton.instance) println(Singleton.instance) println(Singleton.instance) } class Singleton private constructor(){ // 单例,私有的主构造函数,无从构造函数 var code: Int = 0 var msg: String = "" var data: String = "" companion object { public var instance: Singleton = Singleton() @Synchronized // 注解,get线程同步 get } fun print() { println("Result: $code, $msg, $data") } }