3
\$\begingroup\$

Let's say I have 2 repository classes:

public class XRepository {
    private XDao xDao;
    private LiveData<List<X>> allXs;

    public XRepository(Application application) {
        AppDatabase database = AppDatabase.getInstance(application);
        xDao = database.xDao();
        allXs = xDao.getAllXs();
    }
    public void insert(X x) {
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> xDao.insert(x));
    }
    public void update(X x) {
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> xDao.update(x));
    }
    public void delete(X x) {
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> xDao.delete(x));
    }
    public void deleteAll() {
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> xDao.deleteAll());
    }
    public LiveData<List<X>> getAllXs() {
        return allXs;
    }
}

public class YRepository {
    private YDao yDao;
    private LiveData<List<Y>> allYs;

    public YRepository(Application application) {
        AppDatabase database = AppDatabase.getInstance(application);
        yDao = database.yDao();
        allYs = yDao.getAllYs();
    }
    public void insert(Y y) {
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> yDao.insert(y));
    }
    public void update(Y y) {
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> yDao.update(y));
    }
    public void delete(Y y) {
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> yDao.delete(y));
    }
    public void deleteAll() {
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> yDao.deleteAll());
    }
    public LiveData<List<Y>> getAllYs() {
        return allYs;
    }
}

And most of my ViewModels have insert, update, delete methods which uses their corresponding repository instance.

public class XListingFragmentViewModel extends AndroidViewModel {
    private XRepository xRepository;
    private LiveData<List<X>> allXs;

    public XListingsFragmentViewModel(@NonNull Application application) {
        super(application);
        xRepository = new XRepository(application);
        allXs = xRepository.getAllXs();
    }
    public void insert(X x) { xRepository.insert(x); }
    public void update(X x) { xRepository.update(x); }
    public void delete(X x) { xRepository.delete(x); }
    public void deleteAll() { xRepository.deleteAll(); }
    public LiveData<List<X>> getAllXs() { return allXs; }

    .. Other fragment specific methods
}

public class AddEditXFragmentViewModel extends AndroidViewModel {
    private XRepository xRepository;

    public AddEditXFragmentViewModel(@NonNull Application application) {
        super(application);
        xRepository = new XRepository(application);
    }
    public void insert(X x) { xRepository.insert(x); }
    public void update(X x) { xRepository.update(x); }
    public void delete(X x) { xRepository.delete(x); }

    .. Other fragment specific methods
}

public class YListingFragmentViewModel extends AndroidViewModel {
    private YRepository yRepository;
    private LiveData<List<Y>> allYs;

    public XListingsFragmentViewModel(@NonNull Application application) {
        super(application);
        yRepository = new YRepository(application);
        allYs = yRepository.getAllYs();
    }
    public void insert(Y y) { yRepository.insert(y); }
    public void update(Y y) { yRepository.update(y); }
    public void delete(Y y) { yRepository.delete(y); }
    public void deleteAll() { yRepository.deleteAll(); }
    public LiveData<List<Y>> getAllYs() { return allYs; }

    .. Other fragment specific methods
}

public class AddEditYFragmentViewModel extends AndroidViewModel {
    private YRepository yRepository;

    public AddEditYFragmentViewModel(@NonNull Application application) {
        super(application);
        yRepository = new YRepository(application);
    }
    public void insert(Y y) { yRepository.insert(y); }
    public void update(Y y) { yRepository.update(y); }
    public void delete(Y y) { yRepository.delete(y); }

    .. Other fragment specific methods
}

They are very similar to each other and I think I am repeating a lot of codes. Any idea how I can simplify these using OOP? Or some sort of design pattern maybe?
P.S. I am using Room Persistence Library

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Do you have code ownership to the XDao and YDao classes? If you do, then you can change them to implement a common generic Dao<T> interface and do away with a single parameterized Repository<T> class. \$\endgroup\$ Commented Jan 20, 2020 at 13:02

1 Answer 1

1
\$\begingroup\$

As said by @TorbenPutkonen, if you have the ownership on your dao classes then you can parameterize them.

abstract class Repository<X> {
  private LiveData<List<X>> allEntities;
  private Dao<X> dao;

  void insert(X entity);

}

abstract class ListingFragmentViewModel<X> {
  private Repository<X> repository;
  public void insert(X entity) { 
    repository.insert(x); 
  }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.