验证和 DDD - kotlin 数据类

Sur*_*tic 6 validation domain-driven-design kotlin

在 Java 中,我会在域对象中创建构造函数时进行验证,但是在使用 kotlin 中的数据类时,我不知道如何进行类似的验证。我可以在应用程序服务中做到这一点,但我想坚持域对象及其逻辑。最好以示例显示。

public class Example {

    private String name;

    Example(String name) {
        validateName(name);
        this.name = name;
    }
}
Run Code Online (Sandbox Code Playgroud)

在 Kotlin 中,我只有一个数据类,有没有类似于 Java 风格的方法?

data class Example(val name: String)
Run Code Online (Sandbox Code Playgroud)

Ada*_*hip 21

您可以将验证代码放在initializer block. 无论对象是通过主构造函数还是通过copy方法实例化,这都会执行。

data class Example(val name: String) {
    init {
        require(name.isNotBlank()) { "Name is blank" }
    }
}
Run Code Online (Sandbox Code Playgroud)

一个简单的例子:

fun main() {
    println(Example(name = "Alice"))
    println(try { Example(name = "") } catch (e: Exception) { e })
    println(try { Example(name = "Bob").copy(name = "")  } catch (e: Exception) { e })
}
Run Code Online (Sandbox Code Playgroud)

产生:

Example(name=Alice)
java.lang.IllegalArgumentException: Name is blank
java.lang.IllegalArgumentException: Name is blank
Run Code Online (Sandbox Code Playgroud)


Aka*_*dze 8

您可以使用配套工厂方法获得类似的效果 :

data class Example private constructor(val name: String) {
    companion object {
        operator fun invoke(name: String): Example {
            //validateName
            return Example(name)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

...

val e = Example("name")
e.name //validated
Run Code Online (Sandbox Code Playgroud)

  • 尽管构造函数是privet,您仍然可以通过数据类的`copy`方法创建具有无效状态的`Example`。例如:```val ex = Example("validValue")``` 然后是```ex.copy("invalidValue")``` (10认同)
  • 如果存在确定名称是否有效的逻辑,最好使用“ValidatedNameString”类,这使得任何人都无法使用无效字符串 (2认同)