hienlt0610
7/22/2019 - 6:49 AM

Clean Architech

import java.util.ArrayList;
import java.util.List;

public abstract class Mapper<T1, T2> {

  public abstract T2 map(T1 value);

  public abstract T1 reverseMap(T2 value);

  public List<T2> map(List<T1> values) {
    List<T2> returnValues = new ArrayList<>(values.size());
    for (T1 value : values) {
      returnValues.add(map(value));
    }
    return returnValues;
  }

  public List<T1> reverseMap(List<T2> values) {
    List<T1> returnValues = new ArrayList<>(values.size());
    for (T2 value : values) {
      returnValues.add(reverseMap(value));
    }
    return returnValues;
  }
}
/*
 *  Copyright (C) 2017 MINDORKS NEXTGEN PRIVATE LIMITED
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      https://mindorks.com/license/apache-v2
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License
 */

import io.reactivex.Scheduler;

public interface SchedulerProvider {

    Scheduler ui();

    Scheduler computation();

    Scheduler io();

}
/*
 *  Copyright (C) 2017 MINDORKS NEXTGEN PRIVATE LIMITED
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      https://mindorks.com/license/apache-v2
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License
 */

import javax.inject.Inject;

import io.reactivex.Scheduler;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class AppSchedulerProvider implements SchedulerProvider {

    @Inject
    public AppSchedulerProvider() {
    }

    @Override
    public Scheduler ui() {
        return AndroidSchedulers.mainThread();
    }

    @Override
    public Scheduler computation() {
        return Schedulers.computation();
    }

    @Override
    public Scheduler io() {
        return Schedulers.io();
    }

}
/**
 * Copyright (C) 2015 Fernando Cejas Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package namtran.domain.interactor.core;

import io.reactivex.Flowable;
import io.reactivex.Observable;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.subscribers.DisposableSubscriber;
import namtran.domain.executor.SchedulerProvider;
import namtran.domain.repository.IAppRepository;
import namtran.util.Preconditions;

/**
 * Abstract class for a Use Case (Interactor in terms of Clean Architecture).
 * This interface represents a execution unit for different use cases (this means any use case
 * in the application should implement this contract).
 *
 * By convention each UseCase implementation will return the result using a {@link DisposableObserver}
 * that will execute its job in a background thread and will post the result in the UI thread.
 */
public abstract class UseCase<T, Params> {

  private final CompositeDisposable disposables;
  private SchedulerProvider schedulerProvider;
  protected IAppRepository iAppRepository;

  public UseCase(IAppRepository iAppRepository, SchedulerProvider schedulerProvider) {
    this.disposables = new CompositeDisposable();
    this.schedulerProvider = schedulerProvider;
    this.iAppRepository = iAppRepository;
  }

  /**
   * Builds an {@link Flowable} which will be used when executing the current {@link UseCase}.
   */
  protected abstract Flowable<T> buildUseCaseFlowable(Params params);

  /**
   * Builds an {@link Flowable} which will be used when executing the current {@link UseCase}.
   */
  protected abstract Observable<T> buildUseCaseObserve(Params params);

  /**
   * Executes the current use case.
   *
   * @param subscriber {@link DisposableSubscriber} which will be listening to the observable build
   * by {@link #buildUseCaseFlowable(Params)} ()} method.
   * @param params Parameters (Optional) used to build/execute this use case.
   */
  public void execute(DisposableSubscriber<T> subscriber, Params params) {
    Preconditions.checkNotNull(subscriber);
    if (subscriber.isDisposed())
      subscriber.dispose();
    final Flowable<T> observable = this.buildUseCaseFlowable(params)
        .subscribeOn(schedulerProvider.io())
        .observeOn(schedulerProvider.ui());
    addDisposable(observable.subscribeWith(subscriber));
  }

  /**
   * Executes the current use case.
   *
   * @param observer {@link DisposableObserver} which will be listening to the observable build
   * by {@link #buildUseCaseObserve(Params)} ()} method.
   * @param params Parameters (Optional) used to build/execute this use case.
   */
  public void execute(DisposableObserver<T> observer, Params params) {
    Preconditions.checkNotNull(observer);
    if (observer.isDisposed())
      observer.dispose();
    final Observable<T> observable = this.buildUseCaseObserve(params)
            .subscribeOn(schedulerProvider.io())
            .observeOn(schedulerProvider.ui());
    addDisposable(observable.subscribeWith(observer));
  }

  /**
   * Dispose from current {@link CompositeDisposable}.
   */
  public void dispose() {
    if (!disposables.isDisposed()) {
      disposables.dispose();
    }
  }

  /**
   * Dispose from current {@link CompositeDisposable}.
   */
  private void addDisposable(Disposable disposable) {
    Preconditions.checkNotNull(disposable);
    Preconditions.checkNotNull(disposables);
    disposables.add(disposable);
  }
}