Android-cleanarchitecture: Saving With RxJava and the Repository Pattern

Created on 21 Jun 2016  路  3Comments  路  Source: android10/Android-CleanArchitecture

Hi, I have been reading the other issues and they all seem to be related to data retrieval rather than saving data. Both UseCases in the project are for retrieval also.

My question is:

_What should I return (if anything) upon saving an entity and should this be an Observable?_

At the moment, following the whole separation of concerns and mapping entities at boundaries we get:

UserModel > User > UserEntity - (save in repo) - (return saved entity) - UserEntity > User > UserModel

Is this correct or is there a different pattern I should be following for insert and update operations?

discussion question

All 3 comments

In my opinion, if it is just in order to save entities or stuff like that, I would suggest to return an Observable<Void>, then you wouldn't really need to remap it, unless you want to get a fresh copy.
Anyway, if the purpose is only for that, you could also use your own thread executor instead of subscribing to an Observer, therefore you can avoid to return nothing after all.

You can return some kind of object wrapped in an Observable that reflects the result of your operation, for instance you could continue composing your stream of data based on this operation.

Something like this:

Observables<OperationResult> doSomething(SomeObject);

Hi,

How to use the UseCase to create a new entry ? In all UseCase sample, we get the data, so we use execute and pass extra data from constructor. If we create a screen to create a new user, we need to add a new method in UseCase like execute(Data, Subscriber), right ? Or we create a new layer from presenter when user click on create button, we use a factory who create UseCase and in this case we can provide data from constructor ?

Sample for the case when we add execute(Data, Subscriber)

public abstract class UseCase<T> {
     /**
     * Builds an {@link rx.Observable} which will be used when executing the current {@link UseCase}.
     */
    protected abstract Observable buildUseCaseObservable(T data);

    /**
     * Executes the current use case.
     *
     * @param useCaseSubscriber The guy who will be listen to the observable build
     *                          with {@link #buildUseCaseObservable(Object data)}.
     */
    @SuppressWarnings("unchecked")
    public void execute(@NotNull Subscriber useCaseSubscriber) {
        execute(useCaseSubscriber, null);
    }

    /**
     * Executes the current use case.
     *
     * @param useCaseSubscriber The guy who will be listen to the observable build
     *                          with {@link #buildUseCaseObservable(Object data)}.
     */
    @SuppressWarnings("unchecked")
    public void execute(@NotNull Subscriber useCaseSubscriber, @Nullable T data) {
        this.subscription = this.buildUseCaseObservable(data)
                .subscribeOn(Schedulers.from(threadExecutor))
                .observeOn(postExecutionThread.getScheduler())
                .subscribe(useCaseSubscriber);
    }
}

Now we can create a CreateUser case:

/**
 * This class is an implementation of {@link UseCase} that represents a use case for
 * create a new user.
 */
public class CreateUser extends UseCase<User> {

    private final UserRepository userRepository;

    @Inject
    public CreateContact(UserRepository userRepository,
                         ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) {
        super(threadExecutor, postExecutionThread);
        this.userRepository = userRepository;
    }

    @Override
    protected Observable buildUseCaseObservable(@Nullable User user) {
        return userRepository.createContact(user);
    }
}
Was this page helpful?
0 / 5 - 0 ratings