我想在不使用ORM(如Hibernate)的情况下将对象保存并加载到数据库。
假设我有以下课程:
public class Person {
private int age;
public void birthday(){
age++;
}
}
此类不提供get方法,因此封装了内部状态(age)。
如果我想保存对象,我需要一个getter方法来执行以下操作:
insert into TABLE_PERSON (id, age) vales (1, person.getAge());
反过来说,我需要一个setter方法来加载对象:
int age = "Select age FROM Person";
person.setAge(age);
但我不想打破封装(通过实现额外的setter和getter方法)来保存和加载对象。
有可能这样做吗?也许是某种模式(纪念品?)或最佳实践?
提前谢谢!
答案 0 :(得分:2)
在你的情况下它将起作用的方式一个人将负责生成自己的表示。也就是说,您定义PersonImporter和PersonExporter接口以将数据移入和移出Person对象。这些类基本上是Person设计的一部分。所以:
interface PersonImporter {
public int getAge();
public String getId();
}
interface PersonExporter {
public void setDetails(String id, int age);
}
class Person {
private int age;
private String id;
public Person(PersonImporter importer) {
age = importer.getAge();
id = importer.getId();
}
public void export(PersonExporter exporter) {
exporter.setDetails(id, age);
}
}
这并没有完全消除它使用接口控制它的getter和setter。
答案 1 :(得分:0)
这就是我的想法,可能并不完美。
完成数据隐藏的封装。也许,您只是不希望有人为age
属性设置错误的值。
也许你可以介绍一个包装类,它由外部代码使用,只允许该类使用你的Person
类。
如果您创建一个包含public
包装类的文件,请说PersonWrapper
,它为年龄提供getter和setter。但是这些getter和setter可以有你想要的验证逻辑,例如可以为age
设置哪些值,谁可以等等。在同一个文件中,Person
类可以定义为private
但是使用普通的getter和age
param的setter。您的PersonWrapper
只应在某些预定义条件下使用Person
类getter和setter。
通过这种方式,您可以获得更好的封装。
答案 2 :(得分:0)
你提到了纪念品。 Grand有一个名为Snapshot的变体。这是UML类图:
Person
将是模式中的Originator
。
您可以将Memento实例转储到数据库中的二进制对象。
请注意,Memento是Originator的内部类。 createMemento / setMemento是一种单一的get / set,如果你是一个纯粹主义者,可能会打破封装。但是,调用时使用的信息包(Memento)是 no methods 的接口,因此保证了Originator's
状态的封装。如果您正确映射它,这甚至可以与ORM一起使用。
当然,这似乎只是为了避免获取/设置而做了很多工作。你的人/年龄示例不太现实(不是一个很棒的人物模型)。暴露一个人的年龄或出生日期是非常正常的,并且暴露该财产以保持该对象是可以的。封装并不意味着不透露任何东西。这意味着不要暴露太多细节。
例如,我们不要使用age
,而是使用Person.birthday
。它可以在内部存储为YYYY-MM-DD格式的String或使用Date对象。这些细节不会暴露(它将被封装)。这样做也是为了让您可以更改它而不会影响您班级的客户。您隐藏的任何内容都可以更改而不会对客户产生负面影响。
通过揭露一个人的生日,你说“我冒着人将永远生日的风险。”该部分被曝光,因此在不破坏客户的情况下很难改变。
save
中的公共方法(例如load
和Person
)可以处理保存/加载数据库操作。他们可以访问私有字段(age
)并可以完成工作。你说你没有使用ORM,所以你自己就做了。
答案 3 :(得分:0)
这里的一种方法是使用mapper类。创建一个PersonMAP,将类映射到表,并封装该类中的所有数据库操作。
答案 4 :(得分:-2)
我真的不知道如何使用getter / setter打破封装。 Getters和setters尊重封装。事实上,他们是实现目标的手段。