Pull to refresh in Domain Driven Design app

145 views Asked by At

I need to implement pull to refresh in an iOS app, and I came across this thing, in where I don't know how to approach the problem with the best practices of DDD.

The presentation layer has an event to refresh a list, this needs to update the results throwing away the cache and fetching the elements from the backend.

In the Domain layer, my use case talks to a repository, but, since caching is an implementation detail, the repository interface does not expose a 'cleanCache' method, so there is no clean way to refresh cache from a use case. this is more or less the file structure that I have

Domain

  • GetAllTodosUseCase
  • TodosRepository (interface)

Infrastructure

  • InMemoryTodosRepository (cache)
  • RemoteTodosRepository (api)
  • InMemoryWithRemoteTodosRepository (composes cache and api)

Application

  • factories

Presentation

  • UI (talks to an interactor interface)
2

There are 2 answers

1
Andreas Hütter On

Since it seems to be use case specific when it is okay use a cache and when the remote resources need to be fetched, the decision which repository to use best fits to the application layer.

You could use, for instance, a factory which provides the application use cases the concrete repository implementations at runtime, still being dependent on the repository interface only at compile time.

Or you create another repository interface with the same methods and explicitly bind this repository interface to the concrete use case which should use the cache.

1
René Link On

The UI invokes a controller that executes the use case. The controller is responsible for recognizing the user interaction and translating it to an appropriate invocation of the use case. Thus the controller must recognize the pull to refresh and just create a new use case and pass it an "uncached" repository.

Your controller code should contain something like this

 TodosRepository repository;

 if(isPullToRefresh()){
    repository = getRemoteTodosRepository(); 
 } else {
    repository = getInMemoryTodosRepository();
 }

 GetAllTodosUseCase usecase = new GetAllTodosUseCase(repository);
 
 List<???> todos = usecase.getTodos();