question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How should we deal with the growing repository in model layer?

See original GitHub issue

In the todo project we simply have one POJO(Task) and we already have a bloated model layer here. It’s quite common to have dozens of POJOs in a REAL project. And it’s easy to imagine how big the repository would grow. Whenever I want to add amend something, like adding a Owner(of a Task), I have to add so many lines of code in each one of the classes in the model layer. No need to mention that we have to write so many hardcoded SQL statements. Is there a better way to avoid these things?

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:7

github_iconTop GitHub Comments

1reaction
HarlonWangcommented, Jun 26, 2016

Thanks for reply @PopTudor , it’s very helpful to me .

0reactions
ryanhoocommented, Jun 28, 2016

@PopTudor @81813780 Sorry for later answer. 😅

I think it’s better to define the method in the Contract interface.

Why?

Interface is the standard that it defines protocols for implementations to follow. Also, for those who wants to communicate with this, the methods in interface are accountable because you know they will be implemented.

In view-presenter layer we use xxxContract.View to hold the reference instead of using xxxFragment directly.

I got the inspiration from the View-Presenter-Contract, instead of drafting a single contract for both Repository, LocalDataSource, RemoteDataSource to follow(which is a little bit annoying). My contract is like this:

interface UserContract {

   interface Local {
       Observable<User> user();

       // database only
       boolean update(User user);
       boolean delete(User user);
       ...
  }

  interface Remote {
       Observable<User> user();
  }

  Observable<User> user(boolean forceUpdate);
}

And then I implement LocalUserDataSource to handle local db operations, RemoteUserDataSource to handle network request. And finally our UserRepository comes:

class UserRepository {

   UserContract.Local mLocalDataSource;
   UserContract.Remote mRemoteDataSource;

   private UserRepository() {
      mLocalDataSource = new LocalUserDataSource(Injection.provideDbHelper());
      mRemoteDataSource = new RemoteUserDataSource(Injection.provideRESTfulApi());
   }

   public static UserRepository getInstance(){
      ...
   }

   public Observable<User> user(boolean forceUpdate) {
      Observable<User> local = mLocalDataSource.user();
      Observable<User> remote = mRemoteDataSource.user()
                  .doOnNext(user -> mLocalDataSource.save(user));
      if (forceUpdate)
            return remote;
      return Observable.concat(local, remote).first();
   }
}

I wanted to separate the contract into three parts is because they behave differently, both local & remote datasource should only handle their own business.

But if we simply define them in a single contract, it will just add more constraints to our code and brings more confusion to your reviewers. How are you going to implement deleteUser in remote datasource? Yes of course you can just leave it alone. Once I even added @Dreprecated annotations to those empty implementations. LOL

And finally for you confusion:

If you need to expose more methods to presenters, just add it in Contract and then implement it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How should we deal with the growing Repository in a mvp ...
Whenever I want to add or amend something, like adding a Owner(of a Task), I have to add so many lines of code...
Read more >
Principles & Practice in Repository Layer - ProAndroidDev
A repository mediates between domain and data-source. It maps data into domain models, so that the Domain layer only need to deal with...
Read more >
Repository and Services Pattern in a Multilayered architecture
There is one good thing that comes from using repositories, it helps you separate concerns cleanly: the data comes from the repository (it...
Read more >
Data Layer Using the Repository Pattern - Medium
This article contains a description of how the data layer of an Android application can be implemented using the repository pattern.
Read more >
4 Common Mistakes with the Repository Pattern
Your repositories should return domain objects and the client of the repository can decide if it needs to do the mapping. By mapping...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found