[JAVA] Personal Realm Class Design Best Practices (Android)

Introduction

After creating an app that uses Realm several times, I gradually came up with the design and implementation that this might be the best, so I will write it here. (Opposition / improvement is welcome)

Prerequisites

Create a class called RealmHelper. Created to access Realm. Create 1RealmHelper for 1RealmObject, and that RealmHelper is responsible for accessing the object. This will prevent the bloat of one class and clarify the responsibilities of each Helper.

Think about the optimal solution from each viewpoint

In designing, I tried to identify what is necessary from two perspectives.

Required usage

Think about how you can use Realm.

  1. If you want to access in one shot --I want to insert only once on the screen --I want to read the value once and display it on the screen etc ... -** In this case, I want to feel free to call the helper class with a static method without instantiating it. I want the helper to automatically open and close Realm internally. ** **

  2. If you want to get RealmObject from Realm and synchronize --I want to use Realm Adapter --I want to modify the Realm value in real time etc ... -** In this case, you want to keep the realm open until you want to quit. The user (such as Fragment) wants to call the close method as needed. ** **

Ease of implementing classes

It is better to finish the implementation early, and I want to summarize the common processing as much as possible.

Thought composition

--Prepare a class called AbstractRealmHelper as an abstract class. --This class implements the common processing that you want to do with any helper class. --Each child helper class inherits this, implementation is easy + processing is unified

Source code

public abstract class AbstractRealmHelper<T extends RealmObject> {

    protected final Realm mRealm;

    public AbstractRealmHelper() {
        mRealm = getRealm();
    }

    static Realm getRealm() {
        return Realm.getDefaultInstance();
    }

    protected static void executeTransactionOneShot(Realm.Transaction transaction) {
        Realm realm = getRealm();
        realm.executeTransaction(transaction);
        realm.close();
    }

    public abstract void upsert(T t);

    public abstract RealmResults<T> findAll();

    protected void executeTransaction(Realm.Transaction transaction) {
        mRealm.executeTransaction(transaction);
    }

    public void destroy() {
        mRealm.close();
    }
}
public class ItemRealmHelper extends AbstractRealmHelper<ItemRealmObject> {

    public static void insertOneShot(ItemRealmObject itemRealmObject) {
        executeTransactionOneShot(insertTransaction(itemRealmObject));
    }

    private static Realm.Transaction insertTransaction(final ItemRealmObject itemRealmObject) {
        return new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                realm.insertOrUpdate(itemRealmObject);
            }
        };
    }

    @Override
    public void upsert(final ItemRealmObject item) {
        executeTransaction(new Realm.Transaction() {
            @Override
            public void execute(Realm realm) {
                realm.copyToRealmOrUpdate(item);
            }
        });
    }

    @Override
    public RealmResults<ItemRealmObject> findAll() {
        return mRealm.where(ItemRealmObject.class).findAll();
    }
}

Issues, etc.

――At this rate, once you close it, you cannot reopen it (currently it is used as such) --Therefore, the method to close is set to destroy instead of close (relaxation?) --Cannot handle when you want to separate the configuration for each Realm Object ――However, I don't really understand the advantages of separating file names, so I feel that defaultInstance is good. ――Even if you create multiple files, if one RealmObject is modified, you will eventually need migration for every Realm. --Actually, I was thinking of separating the configuration, but I couldn't override the static class, so I couldn't give the child class an implementation, and I got stuck. (I wanted to call getRealm with both static and instance methods. Should I give up the static method and override getRealm in the child class?)

Recommended Posts

Personal Realm Class Design Best Practices (Android)
Best practices for log infrastructure design in container operations