2016-06-29 12 views
5

Dự án của tôi sử dụng kiến ​​trúc sạch. Trong tình huống này, lớp giao diện người dùng tách biệt với lớp Miền. Vì vậy, tôi nghĩ rằng nó sẽ là tốt hơn các lớp UI không sở hữu trường hợp realm. Do doc của realm khuyên bạn nên quản lý cá thể của realm trong vòng đời của Activity, làm thế nào tôi nên đối phó với instance của realm sau đó?Thực hành tốt nhất về quản lý trường hợp realm trong Kiến trúc Sạch là gì?

Để rõ ràng hơn, dự án của tôi quá nặng để thay đổi tất cả các đối tượng mở rộng RealmObject. Vì vậy, tôi sử dụng đối tượng riêng biệt cho dữ liệu liên tục. Khi kết thúc cuộc gọi api, một đối tượng nghiệp vụ chuyển đổi thành một đối tượng realm, ngược lại khi truy vấn từ cõi. Tôi tạo phương pháp như sau:

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

Thực ra, nó hoạt động tốt. Nhưng dưới đây tôi không biết làm thế nào để xử lý trường hợp lĩnh vực đóng cửa.

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

Trả lời

4

Nếu bạn muốn có một tách sạch giữa UI và cơ sở dữ liệu lớp trong mã của bạn, và bạn muốn tóm tắt đi lý cơ sở dữ liệu của bạn để lý tưởng hoạt động của bạn có thể gọi lớp cơ sở dữ liệu mà không biết làm thế nào lớp đó được thực hiện, sau đó Realm có lẽ không phải là những gì bạn đang tìm kiếm.

Đối tượng địa lý được liên kết với các trường hợp realm có nghĩa là nếu bạn lấy một đối tượng từ một đối tượng lĩnh vực và sau đó đóng cá thể đó (bạn phải), bạn không thể sử dụng đối tượng nữa. Mà đánh bại toàn bộ mục đích của việc sử dụng Realm.

Nếu bạn định sử dụng Realm, bạn nên giữ logic liên kết chặt chẽ với hoạt động/dịch vụ của mình, và đừng cố giấu nó trong một lớp riêng biệt để bạn có toàn quyền kiểm soát nó.


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

Cảm ơn bạn đã trả lời. Tôi cập nhật một số chi tiết ở trên. Tôi hiểu theo cách này, nó từ bỏ những lợi thế tuyệt vời nhất của vương quốc. Nhưng kiến ​​trúc của dự án là xác định, vì vậy, có thể sử dụng lĩnh vực trong tình trạng này? –

+0

@ZeatualChang Tôi tưởng tượng 'call' là chức năng cuối cùng trong chuỗi nên bạn có thể đóng cõi đó, xem phần chỉnh sửa.Nó có thể làm việc –

+0

Tôi đã thử điều này, nhưng các nhà khai thác rx hoạt động trên truy vấn không đồng bộ realm phù hợp với chủ đề hoạt động trên. Nó là một chủ đề khác nhau từ một thể hiện realm được mở ra. –

0

Một trong những khía cạnh quan trọng của một kiến ​​trúc sạch là, cô lập của thư viện lớn (ví dụ: Realm). Vì Realm, RealmObject, RealmResults không thể truy cập được bên ngoài Thread mà chúng được tạo ra, nó thậm chí còn quan trọng hơn để giữ cho Realm & Tính toán liên quan đến lĩnh vực được phân lập từ phần còn lại của mã.

Bạn đang sử dụng RxJava trong phương thức queryAsync() của mình và đồng thời bạn đang sử dụng phương thức executeTransactionAsync(), điều này làm mất toàn bộ mục đích sử dụng RxJava. Bạn có thể làm như thế này,

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

Trong một kiến ​​trúc tốt, cho mỗi lớp jsonModel cần có một lớp realmModel tương ứng & một (Data Access Object) DAO. Lớp DAO phải lấy jsonModel làm đối số và phải trả về kết quả jsonModel. Tất cả các hoạt động liên quan đến lĩnh vực phải được hạn chế trong tệp DAO, theo cách đó không có mã nào khác ngoài DAO và realmModel biết về Realm.

Đây là một bài viết về thực hành tốt nhất Realm với một kiến ​​trúc tốt https://medium.com/@Viraj.Tank/realm-integration-in-android-best-practices-449919d25f2f

Cũng là một dự án mẫu chứng minh Lồng ghép Realm trên Android với MVP (Model View Presenter), RxJava, Retrofit, Dagger, Chú thích & Testing. https://github.com/viraj49/Realm_android-injection-rx-test

+0

Tính năng nào của lĩnh vực mà bạn từ bỏ khi sử dụng phương pháp này? –

+0

AFAI không, bạn có thể thực hiện tất cả các hoạt động của Realm mà không bỏ lỡ bất cứ điều gì, Trọng tâm chính của nó là giữ tất cả các công cụ của Realm khỏi phần còn lại của mã. –

+0

@Tim, Sau một cuộc thảo luận dài và một số phát hiện khác, nó chỉ ra bạn bỏ lỡ một vài tính năng của Realm khi sử dụng cách tiếp cận cách ly. ví dụ. Cập nhật tự động của Realm của chế độ xem khi RealmObject được sửa đổi. –

Các vấn đề liên quan