Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stream Episode 13 #64

Merged
merged 10 commits into from
Sep 29, 2018
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package com.joaquimley.transporteta.domain.executor
import java.util.concurrent.Executor

/**
* Executor implementation can be based on different frameworks or techniques of asynchronous
* execution, but every implementation will execute the
* Executor implementation can be based on different frameworks or techniques of asynchronous execution.
*/
interface ThreadExecutor : Executor

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
package com.joaquimley.transporteta.domain.interactor.base

import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor
import io.reactivex.Flowable
import io.reactivex.Single
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import io.reactivex.subscribers.DisposableSubscriber
import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor



/**
Expand All @@ -18,35 +14,17 @@ abstract class FlowableUseCase<T, in Params> constructor(
private val threadExecutor: ThreadExecutor,
private val postExecutionThread: PostExecutionThread) {

private val disposables = CompositeDisposable()

/**
* Builds a [Single] which will be used when the current [FlowableUseCase] is executed.
* Builds a [Flowable] which will be used when the current [FlowableUseCase] is executed.
*/
protected abstract fun buildUseCaseObservable(params: Params? = null): Flowable<T>

/**
* Executes the current use case.
*/
open fun execute(observer: DisposableSubscriber<T>, params: Params? = null) {
val observable = this.buildUseCaseObservable(params)
open fun execute(params: Params? = null): Flowable<T> {
return this.buildUseCaseObservable(params)
.subscribeOn(Schedulers.from(threadExecutor))
.observeOn(postExecutionThread.scheduler) as Flowable<T>
addDisposable(observable.subscribeWith(observer))
}

/**
* Dispose from current [CompositeDisposable].
*/
fun dispose() {
if (!disposables.isDisposed) disposables.dispose()
}

/**
* Dispose from current [CompositeDisposable].
*/
private fun addDisposable(disposable: Disposable) {
disposables.add(disposable)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.joaquimley.transporteta.domain.interactor.base

import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import io.reactivex.disposables.Disposables
import io.reactivex.schedulers.Schedulers

/**
* Abstract class for a UseCase that returns an instance of a [Observable].
*/
abstract class ObservableUseCase<T, in Params> protected constructor(
private val threadExecutor: ThreadExecutor,
private val postExecutionThread: PostExecutionThread) {

private val subscription = Disposables.empty()

/**
* Builds a [Observable] which will be used when the current [ObservableUseCase] is executed.
*/
protected abstract fun buildUseCaseObservable(params: Params): Observable<T>

/**
* Executes the current use case.
*/
fun execute(params: Params): Observable<T> {
return this.buildUseCaseObservable(params)
.subscribeOn(Schedulers.from(threadExecutor))
.observeOn(postExecutionThread.scheduler)
}

/**
* Unsubscribes from current [Disposable].
*/
fun unsubscribe() {
if (!subscription.isDisposed) {
subscription.dispose()
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.joaquimley.transporteta.domain.interactor.base

import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor
import io.reactivex.Single
import io.reactivex.disposables.Disposable
import io.reactivex.disposables.Disposables
import io.reactivex.schedulers.Schedulers

/**
* Abstract class for a UseCase that returns an instance of a [Single].
*/
abstract class SingleUseCase<T, in Params> protected constructor(
private val threadExecutor: ThreadExecutor,
private val postExecutionThread: PostExecutionThread) {

private val subscription = Disposables.empty()

/**
* Builds a [Single] which will be used when the current [SingleUseCase] is executed.
*/
protected abstract fun buildUseCaseObservable(params: Params): Single<T>

/**
* Executes the current use case.
*/
fun execute(params: Params): Single<T> {
return this.buildUseCaseObservable(params)
.subscribeOn(Schedulers.from(threadExecutor))
.observeOn(postExecutionThread.scheduler)
}

/**
* Unsubscribes from current [Disposable].
*/
fun unsubscribe() {
if (!subscription.isDisposed) {
subscription.dispose()
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.joaquimley.transporteta.domain.interactor.transport

import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor
import com.joaquimley.transporteta.domain.interactor.base.CompletableUseCase
import com.joaquimley.transporteta.domain.interactor.base.SingleUseCase
import com.joaquimley.transporteta.domain.repository.TransportRepository
import io.reactivex.Completable
import io.reactivex.Single
import javax.inject.Inject

class CancelEtaRequestUseCase @Inject constructor(private val transportRepository: TransportRepository,
threadExecutor: ThreadExecutor,
postExecutionThread: PostExecutionThread) :
CompletableUseCase<Int?>(threadExecutor, postExecutionThread) {
/**
* Builds a [Completable] which will be used when the current [Completable] is executed.
*/
public override fun buildUseCaseObservable(params: Int?): Completable {
return transportRepository.cancelTransportEtaRequest(params)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.joaquimley.transporteta.domain.interactor.transport

import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor
import com.joaquimley.transporteta.domain.interactor.base.ObservableUseCase
import com.joaquimley.transporteta.domain.interactor.base.SingleUseCase
import com.joaquimley.transporteta.domain.model.Transport
import com.joaquimley.transporteta.domain.repository.TransportRepository
import io.reactivex.Observable
import io.reactivex.Single
import javax.inject.Inject

class GetTransportUseCase @Inject constructor(private val transportRepository: TransportRepository,
threadExecutor: ThreadExecutor,
postExecutionThread: PostExecutionThread) :
ObservableUseCase<Transport, String>(threadExecutor, postExecutionThread) {
/**
* Builds a [Single] which will be used when the current [SingleUseCase] is executed.
*/
public override fun buildUseCaseObservable(params: String): Observable<Transport> {
return transportRepository.getTransport(params)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.joaquimley.transporteta.domain.interactor.transport

import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor
import com.joaquimley.transporteta.domain.interactor.base.ObservableUseCase
import com.joaquimley.transporteta.domain.model.Transport
import com.joaquimley.transporteta.domain.repository.TransportRepository
import io.reactivex.Observable
import javax.inject.Inject

class RequestEtaUseCase @Inject constructor(private val transportRepository: TransportRepository,
threadExecutor: ThreadExecutor,
postExecutionThread: PostExecutionThread) :
ObservableUseCase<Transport, Int>(threadExecutor, postExecutionThread) {
/**
* Builds a [Observable] which will be used when the current [ObservableUseCase] is executed.
*/
public override fun buildUseCaseObservable(params: Int): Observable<Transport> {
return transportRepository.requestTransportEta(params)
}
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
package com.joaquimley.transporteta.domain.interactor.favorites
package com.joaquimley.transporteta.domain.interactor.transport.favorites

import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor
import com.joaquimley.transporteta.domain.interactor.base.CompletableUseCase
import com.joaquimley.transporteta.domain.interactor.base.FlowableUseCase
import com.joaquimley.transporteta.domain.model.Transport
import com.joaquimley.transporteta.domain.repository.FavoritesRepository
import io.reactivex.Completable
import io.reactivex.Flowable
import javax.inject.Inject

class ClearAllTransportsAsFavoriteUseCase @Inject constructor(private val favoritesRepository: FavoritesRepository,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.joaquimley.transporteta.domain.interactor.favorites
package com.joaquimley.transporteta.domain.interactor.transport.favorites

import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.joaquimley.transporteta.domain.interactor.favorites
package com.joaquimley.transporteta.domain.interactor.transport.favorites

import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
package com.joaquimley.transporteta.domain.interactor.favorites
package com.joaquimley.transporteta.domain.interactor.transport.favorites

import com.joaquimley.transporteta.domain.executor.PostExecutionThread
import com.joaquimley.transporteta.domain.executor.ThreadExecutor
import com.joaquimley.transporteta.domain.interactor.base.CompletableUseCase
import com.joaquimley.transporteta.domain.interactor.base.FlowableUseCase
import com.joaquimley.transporteta.domain.model.Transport
import com.joaquimley.transporteta.domain.repository.FavoritesRepository
import io.reactivex.Completable
import io.reactivex.Flowable
import javax.inject.Inject

class MarkTransportAsNoFavoriteUseCase @Inject constructor(private val favoritesRepository: FavoritesRepository,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package com.joaquimley.transporteta.domain.model

data class Transport(val id: String, val name: String, val code: Int, val latestEta: String, val isFavorite: Boolean = false,
val type: String)
data class Transport(val id: String, val name: String, val code: Int, val latestEta: String,
val isFavorite: Boolean = false, val type: String)

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.joaquimley.transporteta.domain.repository

import com.joaquimley.transporteta.domain.model.Transport
import io.reactivex.Completable
import io.reactivex.Flowable

class MockFavoritesRepository: FavoritesRepository {
override fun markAsFavorite(favorite: Transport): Completable {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}

override fun removeAsFavorite(transport: Transport): Completable {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}

override fun getAll(): Flowable<List<Transport>> {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}

override fun clearFavorites(): Completable {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.joaquimley.transporteta.domain.repository

import com.joaquimley.transporteta.domain.model.Transport
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single

/**
* Interface defining methods for how the data layer can pass data to and from the Domain layer.
Expand All @@ -10,11 +12,15 @@ import io.reactivex.Completable
*/
interface TransportRepository {

fun getTransport(transportId: String)
fun requestTransportEta(transportCode: Int): Observable<Transport>

fun saveTransport(favorite: Transport): Completable
fun cancelTransportEtaRequest(transportCode: Int?): Completable

fun saveTransports(favoriteList: List<Transport>): Completable
fun getTransport(transportId: String): Observable<Transport>

fun saveTransport(transport: Transport): Completable

fun saveTransport(transportList: List<Transport>): Completable

fun deleteTransport(transport: Transport): Completable

Expand Down
Loading