我想在不使用 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 类图:
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)方法(例如,save
和 load
)可以处理保存/加载数据库操作。他们将有权访问私有(private)字段 (age
) 并可以完成工作。你说你没有使用 ORM,那么你就自己做。
关于java - 在不破坏封装的情况下保存和加载对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24921227/