Search code examples
androidarchitecturerealm

How to use Realm "live" objects and keep database layer decoupled from other layers(business, UI, etc)?


I'm playing around with Realm for Android.

I like the auto-updating objects idea, but I have a concern about it regarding software architecture.

I've seen that many proposed architectures specify a layer to handle data/database access, and ideally the higher layers will not know specifics about the database implementation. This will help with maintainability, modularity, etc.

When you use Realm objects, if you want to take advantage of their auto-updating property, the most common way I can think of doing that is having those objects on Activity/Fragment code. Now let's suppose that the user just edited data on screen(that is represented by a realm object under the hood) and is saving these edits. If you call this object's setter, that will actually be a database operation and you will need a transaction. By creating a database transaction on activity/fragment code, architecture falls apart, as you are making your UI/business layers aware of database implementation details.

My question is: how to take advantage of Realm auto-updating objects in a way that doesn't hurt architecture?

Side note: I've used Realm in a recent app and for every query, we had to copy the results to unmanaged objects so that we could send them up to UI/business layers. I don't think that is the best strategy out there, as we could not use Realm to its full potential.


Solution

  • After some research, I came to the conclusion that indeed one needs to make a major choice about integrating Realm to an app: Safe integration x Deep Integration.

    Safe Integration

    Here you will isolate Realm from the rest of the app code. In order to do that, you won't be able to use the auto-updating/zero-copy of Realm. Instead you will have unmanaged copies, to make sure that anywhere the objects are accessed, you won't have problems with different threads accessing the same objects. Testing is easier this way.

    Deep Integration

    Here you will use Realm to its full potential, lazily loading data when requested. The downside is that other layers of the code will be aware of Realm, in the sense that they will need to make sure that managed objects are not accessed by different threads. This options potentially involves heavy refactoring if you are not starting a new app, but will bring the performance benefits of the zero-copy approach.

    My answer is based on these articles: https://medium.com/@Viraj.Tank/realm-integration-in-android-best-practices-449919d25f2f#.ms3nenq0m and https://medium.com/@Viraj.Tank/deep-integration-of-realm-in-android-production-code-part-2-with-mvp-4cf44ab6289d#.qq4p12mtw