Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best practice of managing realm instance in Clean Architecture?

Tags:

android

realm

My project using clean architecture. In this situation, the UI layer is separate from Domain layer. So I think it would be better the UI layer doesn't own realm instance. As realm's doc recommend managing the realm instance in Activity's lifecycle, how should I deal with the realm instance then?

To be more clear, my project is too heavy to change all objects extends RealmObject. So I use separate object to persistent data. When the api call finish, a business object convert to a realm object, opposite when query from realm. I create the method like this:

public void insert(T object){
    final Realm realm = RealmProvider.getRealm();
    realm.executeTransactionAsync(new Realm.Transaction() {
        @Override
        public void execute(Realm realm) {
            realm.copyToRealmOrUpdate(createRealmObject(object));
        }
    }, new Realm.Transaction.OnSuccess() {
        @Override
        public void onSuccess() {
            realm.close();
        }
    }, new Realm.Transaction.OnError() {
        @Override
        public void onError(Throwable error) {
            realm.close();
        }
    });
}

Actually, it works fine. But below I don't know how to handle closing realm instance.

public Observable<T> queryAsync(Condition<? extends RealmObject> condition) {
    final Realm realm = RealmProvider.getRealm();
    return condition.getQuery(realm).findFirstAsync()
            .asObservable()
            .filter(new Func1<RealmObject, Boolean>() {
                @Override
                public Boolean call(RealmObject realmObject) {
                    return realmObject.isLoaded();
                }
            })
            .map(new Func1<RealmObject, T>() {
                @Override
                public T call(RealmObject realmObject) {
                    return createObjectFromRealm(realmObject);
                }
            });
}
like image 393
Zeatual Chang Avatar asked Oct 18 '22 06:10

Zeatual Chang


1 Answers

If you want a clean separation between UI and database layers in your code, and you want to abstract away your database logic so that ideally your activity can call database layer without knowing how that layer is implemented, then Realm is probably not what you're looking for.

Realm objects are tied to realm instances which means that if you retrieve an object from a realm instance and then close that instance (which you must), you can no longer use the object. Which defeats the entire purpose of using Realm.

If you are going to use Realm, you should keep the realm logic closely tied to your activities/services etc, and don't try to hide it in a separate layer, so that you have full control over it.


        .map(new Func1<RealmObject, T>() {
            @Override
            public T call(RealmObject realmObject) {
                Object o = createObjectFromRealm(realmObject);
                realm.close();
                return o;
            }
        });
like image 145
Tim Avatar answered Oct 21 '22 01:10

Tim