恢复对象的默认值

时间:2019-04-11 19:36:43

标签: kotlin singleton

我正在使用两个不同的对象,它们的使用方式类似于单例。 在某个时候,我希望用户能够注销并再次找到对象的默认值。

有没有比覆盖这样的值更好的方法了?

objectA.variableA = ""
objectA.variableB = ""
objectA.variableC = ""

2 个答案:

答案 0 :(得分:0)

对象也可以具有功能,因此,我绝不会尝试从该对象外部将对象状态重置为其初始状态。而是给它提供一个为您完成的功能。

此外,您还想确保重置功能与初始化对象的方式保持同步。您不想在两个不同的地方都保持“默认”的语义,无论是在对象中还是对象外部。

因此,这是一个执行此操作的示例:

object LoginSession {
    lateinit var variableA: String
    lateinit var variableB: String
    lateinit var variableC: String

    init {
        reset()
    }

    fun reset() {
        variableA = ""
        variableB = ""
        variableC = ""
    }
}

现在,如果您想重置对象的状态,则可以调用LoginSession.reset()

答案 1 :(得分:-1)

在我看来,这不是使用“对象”的最佳方法。如果要创建一些Session,最好使用该类的伴侣对象。为了使架构更整洁,将更好地创建具有(im)可变状态的Session的工厂。

class LoginSession private constructor(
    val variableA: String, // here you can also define default value
    val variableB: String,
    val variableC: String
) {

    companion object {
        fun create(a: String, b: String, c: String) = LoginSession(a, b, c)    
    }

}

但是,如果您坚持认为不需要单调,则可以修改以下决定:

class LoginSession private constructor(
        val variableA: String, // here you can also define default value
        val variableB: String,
        val variableC: String
) {

    companion object {
        var instance: LoginSession? = null

        fun create(a: String, b: String, c: String) = if(instance != null) instance 
            else LoginSession(a, b, c).apply {
                    instance = this
                }

        fun reCreate(a: String, b: String, c: String): LoginSession? {
            instance = null
            return create(a, b, c)
        }

    }

}

此解决方案可以为您的项目提供更大的灵活性,因为您可以根据需要使用LoginSession单例的状态进行操作,而不会产生任何后果,例如NPE或var中的错误值。而且,正如我所认为的那样,此代码更加简洁和可扩展。

U.P.D

此外,我建议您遵循鲍勃·马丁(Bob Martin's)和史蒂夫·麦康奈尔(Steve McConnell)的建议,它们说:“如果函数/方法中有2个以上的参数,请尝试将它们加入1个DTO(数据传输对象)中”。

data class SessionDTO(val variableA: String, val variableB: String, val variableC: String)

class LoginSession private constructor(val session: SessionDTO) {

    companion object {
        var instance: LoginSession? = null

        fun create(session: SessionDTO) = if(instance != null) instance 
            else LoginSession(session).apply {
                    instance = this
                }

        fun reCreate(session: SessionDTO): LoginSession? {
            instance = null
            return create(session)
        }

    }

}

因此,在这种情况下,您将获得一些好处:

  • 您具有不变性,没有任何副作用。您的数据在您的应用程序的任何部分都有一个可用值。尽可能使用更多的不变性。如果SessionDTO中的字段之一将更改,则必须重新创建登录会话。这是正确的方法,因为对象的状态已更改。阅读https://www.elegantobjects.org/,它将有很多解释。
  • 您具有灵活且可扩展的DTO,可以根据需要及时进行修改。
  • 您可以手动控制LoginSession状态。您可以创建/重新创建/销毁它的实例。 Kotlin的Object并没有告诉您这一点。

最后,我要说对象不是万灵丹。它旨在创建简单的单例。并且像工程师一样思考,您必须在基本实现和更复杂的模式之间选择正确的方法。例如,恕我直言,这是使用Kotlin对象的最佳方法(我从“ Kotlin in action”一书中摘下来并做了一些修改):

object Payroll {

   /*
       it's mocked method, imagine that inside it called network request, 
       or request in database, or from local storage(json-file, xml-file) 
       or something like this.
   */
   val employees: List<Employer>
       get() = Storage.loadAllEmployees() 

   /*
       So, you can in any time call method `calculateSalary` in any part
       of your application, and calculation algorithm will 
       evaluate salary for all current employers in system. 
   */
   fun calculateSalary() {
       for(person in employees) {
           // some evaluation algorithm 
       }  
   }
}