问题
I am using Realm as a data module in my android application, though I am running into some problems regarding how to assign custom methods to Realm objects. In the iOS coredata module, you have NSObjects which save to memory and also permit malleability within their respective classes. What sort of system can I use to get around this? I tried making "Parent Classes" for all of my realm objects, but this didn't work.
For example: "TeacherRealm" would only contain the getters and setters for a teacher object, while "TeacherParent" would allow the user to run certain algorithms to find data for a teacher. In the TeacherParent class, I tried initializing a TeacherRealm and in TeacherRealm, I provided a getter and setter for the TeacherParent object. Low and behold, my TeacherRealm object class did not support a custom TeacherParent object.
Has anyone encountered this problem/found a solution to it? I know this sounds confusing, though I can provide more information if necessary
回答1:
EDIT: Realm 0.88.0 has enabled the usage of custom methods, and you can also implement interfaces with your Realm Objects. But I'm keeping my repository pattern that was the original answer below. Latest version at the time of writing is 0.88.1.
I firmly believe that data objects should only contain data, and the logic should be separate.
public interface RealmRepository<T extends RealmObject, ID extends Serializable> {
T findOne(Realm realm, ID id);
RealmResults<T> findAll(Realm realm);
void insertOrUpdate(Realm realm, T t);
void insertOrUpdate(Realm realm, Collection<T> t);
T saveOrUpdate(Realm realm, T t);
RealmList<T> saveOrUpdate(Realm realm, RealmList<T> tList);
RealmQuery<T> query(Realm realm);
void delete(Realm realm, ID id);
void delete(Realm realm, T t);
void deleteAll(Realm realm, RealmResults<T> realmResults);
void deleteEveryObject(Realm realm);
long count(Realm realm);
}
And
public abstract class BaseRealmRepositoryImpl<T extends RealmObject, ID extends Serializable>
implements RealmRepository<T, ID> {
protected Class<T> clazz;
public BaseRealmRepositoryImpl(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public RealmResults<T> findAll(Realm realm) {
return query().findAll();
}
@Override
public void insertOrUpdate(Realm realm, T t) {
realm.insertOrUpdate(t);
}
@Override
public void insertOrUpdate(Realm realm, Collection<T> collection) {
realm.insertOrUpdate(collection);
}
@Override
public T saveOrUpdate(Realm realm, T t) {
return realm.copyToRealmOrUpdate(t);
}
@Override
public RealmList<T> saveOrUpdate(Realm realm, RealmList<T> list) {
RealmList<T> realmList = new RealmList<>();
for(T t : realm.copyToRealmOrUpdate(list)) {
realmList.add(t);
}
return realmList;
}
@Override
public RealmQuery<T> query(Realm realm) {
return realm.where(clazz);
}
@Override
public void deleteEveryObject(Realm realm) {
realm.delete(clazz);
}
@Override
public void delete(Realm realm, T t) {
t.deleteFromRealm();
}
@Override
public void deleteAll(Realm realm, RealmResults<T> realmResults) {
realmResults.deleteAllFromRealm();
}
@Override
public long count(Realm realm) {
return query().count();
}
}
And
public abstract class StringRealmRepositoryImpl<T extends RealmObject>
extends BaseRealmRepositoryImpl<T, String>
implements RealmRepository<T, String> {
public StringRealmRepositoryImpl(Class<T> clazz) {
super(clazz);
}
@Override
public T findOne(Realm realm, String id) {
return query(realm).equalTo(getIdFieldName(), id).findFirst();
}
@Override
public void delete(Realm realm, String id) {
delete(realm, findOne(realm, id));
}
}
And
public class TeacherRealm extends RealmObject {
@PrimaryKey
private String id;
//getter, setter, etc.
}
And
public class TeacherRepositoryImpl
extends StringRealmRepositoryImpl<TeacherRealm>
implements TeacherRepository {
public TeacherRepositoryImpl() {
super(TeacherRealm.class);
}
}
And repositories are extensible.
回答2:
I'm working through a similar question. My approach is going to be to use static 'helper' methods to achieve all additional logic. Passing an instance of my object type in the method call.
回答3:
I have the same situation to find a work around for custom logic in realmObjects.
I abused the builder pattern for a comfortable way.
Example:
public class Information extends RealmObject {
@PrimaryKey
private String id;
private int value;
private String text;
//getter and setter for id, value and text
//Helps to create and commit a information realm object
public static class Create {
private Realm realm;
private Information information;
public Create() {
this.realm = Realm.getDefaultInstance();
this.realm.beginTransaction();
this.information = realm.createObject(Information.class);
//init realmObject with defauls
this.information.setId(UUID.randomUUID().toString());
this.information.setValue(0);
this.information.setText("");
//space for additional logic
}
public Create setValue(int val) {
this.information.setValue(val);
//space for additional logic
return this;
}
public Create setText(String s) {
this.information.setText(s);
//space for additional logic
return this;
}
public Information commit() {
//space for additional logic
this.realm.commitTransaction();
return this.information;
}
}
//Helps to modify and commit a information realm object
public static class Modify {
private Realm realm;
private Information information;
public Modify(Information information) {
this.realm = Realm.getDefaultInstance();
this.information = information;
this.realm.beginTransaction();
}
public Modify setValue(int val) {
this.information.setValue(val);
//space for additional logic
return this;
}
public Modify setText(String s) {
this.information.setText(s);
//space for additional logic
return this;
}
public void commit() {
//space for additional logic
this.realm.commitTransaction();
}
}
}
How to use
//create a reamlobject
Information info = new Information.Create()
.setText("Hello World");
.commit();
//modify the created info object
new Information.Modify(info)
.setValue(1)
.commit();
来源:https://stackoverflow.com/questions/31369602/custom-methods-in-realmobjects-solution