2016-06-29 5 views
5

Мой проект с использованием чистой архитектуры. В этой ситуации слой пользовательского интерфейса отделен от уровня домена. Поэтому я думаю, что было бы лучше, если бы слой пользовательского интерфейса не обладал экземпляром realm. Как правило, doc рекомендует управлять экземпляром realm в жизненном цикле Activity, как я должен обращаться с экземпляром области тогда?Какова наилучшая практика управления экземпляром области в чистой архитектуре?

Чтобы быть более понятным, мой проект слишком тяжелый, чтобы изменить все объекты, простирающиеся на RealmObject. Поэтому я использую отдельный объект для постоянных данных. Когда завершение вызова api, бизнес-объект преобразуется в объект области, напротив, когда запрос из области. Я создаю метод следующим образом:

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(); 
     } 
    }); 
} 

На самом деле, он отлично работает. Но ниже я не знаю, как обращаться с закрывающим экземпляром области.

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); 
       } 
      }); 
} 

ответ

4

Если вы хотите четкое разделение между UI и базы данных слоев в вашем коде, и вы хотите, чтобы абстрагироваться от вашей логики базы данных, так что в идеале ваша деятельность может назвать слой базы данных, не зная, как реализован этот слой, затем Realm вероятно, не то, что вы ищете.

Объекты области привязаны к экземплярам царства, что означает, что если вы извлекаете объект из экземпляра царства, а затем закрываете этот экземпляр (который вы должны), вы больше не сможете использовать этот объект. Который побеждает всю цель использования Королевства.

Если вы собираетесь использовать Realm, вы должны поддерживать логику сферы, тесно связанную с вашими действиями/сервисами и т. Д., И не пытайтесь скрыть ее в отдельном слое, чтобы у вас был полный контроль над ней.


 .map(new Func1<RealmObject, T>() { 
      @Override 
      public T call(RealmObject realmObject) { 
       Object o = createObjectFromRealm(realmObject); 
       realm.close(); 
       return o; 
      } 
     }); 
+0

Спасибо за ответ. Я обновляю некоторые подробности выше. Я так понимаю, что он отказывается от самых удивительных преимуществ царства. Но архитектура проекта определена, поэтому можно ли использовать область в этом состоянии? –

+0

@ZeatualChang Я думаю, что 'call' - последняя функция в цепочке, поэтому вы можете закрыть область там, см. Редактирование.Это может работать –

+0

Я пробовал это, но операторы rx работают над асинхронным запросом арифметического потока witch. Это другой поток из одного экземпляра области. –

0

Одним из основных аспектов чистой архитектуры, выделение крупных библиотек (т.е. Realm). Поскольку Realm, RealmObject, RealmResults недоступны за пределами потока, в котором они созданы, это делает еще более важным сохранение Realm & Расчеты, связанные с Realm, выделенные из остальной части кода.

Вы используете RxJava в своем методе queryAsync(), и в то же время вы используете метод executeTransactionAsync(), который бросает вызов всей цели использования RxJava. Вы могли бы сделать так,

public void insert(T object){ 
    final Realm realm = RealmProvider.getRealm(); 
    realm.executeTransaction(realm1 -> 
    realm1.copyToRealmOrUpdate(createRealmObject(object))); 
    realm.close(); 
} 

В хорошей архитектуре, для каждого класса jsonModel должен быть соответствующий realmModel класс & а (Object Data Access) DAO. Класс DAO должен принимать jsonModel в качестве аргумента и должен возвращать jsonModel в качестве результата. Все операции, связанные с Realm, должны быть ограничены в файле DAO, таким образом, ни один из кода, кроме DAO и realmModel, не знает о Realm.

Вот статья о Realm передовой практике с хорошей Architechture https://medium.com/@Viraj.Tank/realm-integration-in-android-best-practices-449919d25f2f

Также образец проекта, демонстрирующего Интеграция Realm на Android с MVP (Model View Presenter), RxJava, дооборудования, Dagger, аннотаций & тестирования. https://github.com/viraj49/Realm_android-injection-rx-test

+0

Какие особенности области вы отказываетесь от использования этого подхода? –

+0

AFAI none, вы можете делать все операции в Realm, не пропуская ни на что, основное внимание уделяется сохранению всего материала Realm от остальной части кода. –

+0

@Tim, после долгого обсуждения и некоторых других выводов вы обнаружите, что у вас есть несколько возможностей Realm при использовании подхода изоляции. например Автоматическое обновление Realm в представлении, когда RealmObject изменен. –