java - 在不破坏封装的情况下保存和加载对象

标签 java database design-patterns encapsulation memento

我想在不使用 ORM(如 Hibernate)的情况下将对象保存和加载到数据库。

假设我有以下类(class):

public class Person {
    private int age;

    public void birthday(){
        age++;
    }
 }

这个类没有提供get方法,所以内部状态(年龄)被封装了。

如果我想保存对象,我需要一个 getter 方法来执行以下操作:

insert into TABLE_PERSON (id, age) vales (1, person.getAge());

另一方面,我需要一个 setter 方法来加载对象:

int age = "Select age FROM Person";
person.setAge(age);

但我不想为了保存和加载对象而破坏封装(通过实现额外的 setter 和 getter 方法)。

有没有可能做到这一点?也许是某种模式(纪念品?)或最佳实践?

提前致谢!

最佳答案

您提到了 Memento。有一个变体叫做 Snapshot由 Grand 记录。这是 UML 类图:

Snapshot pattern

Person 将是模式中的 Originator

您可以将 Memento 实例转储到数据库中的二进制对象。

请注意,Memento 是 Originator 的内部类。 createMemento/setMemento 是一种单一的获取/设置,如果您是纯粹主义者,它可能会破坏封装。但是,调用中使用的信息包(Memento)是一个没有无方法的接口(interface),因此Originator 的 状态的封装是有保证的。如果您正确映射,这甚至可以与 ORM 一起使用。

当然,为了避免 get/set,这似乎需要做很多工作。您的 Person/age 示例不太现实(不是一个很好的 Person 模型)。暴露一个人的年龄或出生日期是很正常的,并且暴露该属性以持久化该对象是可以的。封装并不意味着不泄露任何内容。这意味着不要暴露太多细节。

例如,我们不使用age,而是使用Person.birthday。这可以在内部存储为 YYYY-MM-DD 格式的字符串或使用 Date 对象。这样的细节不会暴露(它会被封装)。这样做也是为了您可以更改它而不影响您类(class)的客户。您隐藏的任何内容都可以更改,而不会对客户产生负面影响。

通过公开一个人的生日,你说“我冒着 Person 永远有生日的风险。”那部分是公开的,因此在不破坏客户的情况下很难改变。

评论后编辑

Person 中的公共(public)方法(例如,saveload)可以处理保存/加载数据库操作。他们将有权访问私有(private)字段 (age) 并可以完成工作。你说你没有使用 ORM,那么你就自己做。

关于java - 在不破坏封装的情况下保存和加载对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24921227/

相关文章:

java - 为什么我的 Java Applet 中的 Swing 在鼠标快速悬停时会闪烁?

Javamail 更改端口号

java - 如何在sqlite3数据库中插入数据

java - 是否有任何模式可用于实现 holder 对象的可变和不可变版本?

ios - VIPER - Interactor 是否应该只返回必要的信息?

JavaFX "Enter"和 "Tab"事件

Java 泛型问题 : type parameter E is not within its bound

php - 关于mysql和mysqli的使用

mysql错误: Warning: #1265 Data truncated for column 'empatt_date' at row 1

java - 业务代表与服务定位器