我正在使用两个不同的对象,它们的使用方式类似于单例。 在某个时候,我希望用户能够注销并再次找到对象的默认值。
有没有比覆盖这样的值更好的方法了?
objectA.variableA = ""
objectA.variableB = ""
objectA.variableC = ""
答案 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)
}
}
}
因此,在这种情况下,您将获得一些好处:
最后,我要说对象不是万灵丹。它旨在创建简单的单例。并且像工程师一样思考,您必须在基本实现和更复杂的模式之间选择正确的方法。例如,恕我直言,这是使用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
}
}
}