gpt4 book ai didi

java - 如何在持久层和领域对象之间正确映射

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:07:10 26 4
gpt4 key购买 nike

假设我有一个代表一个人的域 java 类:

class Person {

private final String id; // government id
private String name;
private String status;

private Person(String id, String name) {
this.id = id;
this.name = name;
this.status = "NEW";
}

Person static createNew(String id, String name) {
return new Person(id, name);
}

void validate() {
//logic
this.status = "VALID";
}


public static final class Builder {

private String id;
private String name;
private String status;

private Builder() {
}

public static Builder aPerson() {
return new Builder();
}

public Builder id(String id) {
this.id = id;
return this;
}

public Builder name(String name) {
this.name = name;
return this;
}

public Builder status(String status) {
this.status = status;
return this;
}

public Person build() {
Person person = new Person(id, name);
person.status = this.status;
return person;
}
}

我将这个域类对象存储在数据库中,常规类具有相同的字段 + getter 和 setter。目前,当我想存储对象时,我创建了新的 PersonDocument(数据存储在 mongo 中),使用 getter 和 setter 并保存它。当我想从数据库中获取它时,它变得很复杂。我希望我的域对象只公开必要的内容,对于目前的业务逻辑来说,它只是创建和验证。很简单:

Person p = Person.createNew("1234", "John");
p.validate();
repository.save(p);

另一方面它变得复杂,目前有一个构建器允许在任何状态下创建对象。我们确实相信存储在 DB 中的数据具有适当的状态,因此可以以这种方式创建它,但缺点是有一个可用的公共(public) API,任何人都可以做任何事情。

最初的想法是使用 MapStruct java 映射库,但它确实使用 setter 来创建对象,并且应该避免在域类中公开 setter(据我所知)。

有什么正确的建议吗?

最佳答案

您的问题可能来自两个相互冲突的要求:

  1. 您只想公开业务方法。
  2. 您也想公开数据,因为您希望能够在对象外部实现序列化/反序列化。

其中之一必须给予。老实说,大多数人遇到这个问题都会忽略第一个,直接引入setter/getter。另一种选择当然是忽略第二种,直接在对象中引入序列化/反序列化。

例如,您可以引入方法 Document toDocument() 到对象中 来生成 Mongo 兼容的 json 文档,以及 Person fromDocument(Document) 反序列化。

大多数人不喜欢这种解决方案,因为它将技术“耦合”到对象上。这是好事还是坏事?取决于您的用例。您要针对哪一项进行优化:更改业务逻辑还是更改技术?如果您不打算经常更改技术并且不打算在完全不同的应用程序中使用相同的类,则没有理由分离技术。

关于java - 如何在持久层和领域对象之间正确映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53260217/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com