oldergod / android-architecture

MVI architecture Implementation of the ToDo app.
Apache License 2.0
669 stars 70 forks source link

[q] Extension instead of ObservableTransformer? #54

Closed roosale closed 5 years ago

roosale commented 5 years ago

Forgive me, I'm a bit of a Kotlin & Rx noob. Is there any problem with using Kotlin extension methods instead of ObservableTransformers for the 'ActionProcessorHolder' classes? The processors become a bit more concise, and from what I've read ObservableTransformers exist to make up for the lack of extensions in Java.

private val updateTaskProcessor =
            ObservableTransformer<UpdateTaskAction, UpdateTaskResult> { actions ->
                actions.flatMap { action ->
                    tasksRepository.saveTask(
                            Task(title = action.title, description = action.description, id = action.taskId)
                    ).andThen(Observable.just(UpdateTaskResult))
                }
            }

becomes

private fun Observable<UpdateTaskAction>.updateTaskProcessor() = flatMap { action ->
        tasksRepository.saveTask(
                Task(title = action.title, description = action.description, id = action.taskId))
                .andThen(Observable.just(UpdateTaskResult))
    }

Thanks for the project, I've found it extremely helpful.

oldergod commented 5 years ago

To be honest I've never thought about this, that's a great idea. I don't see any drawback for now, it's worth giving it a try!

roosale commented 5 years ago

Gets a bit harder to follow calling the root processor from the view model because the holder class is stateful, ends up as

// processor holder

fun Observable<TasksAction>.actionProcessor() = publish {  
  ...
}

// view model

fun compose(): Observable<TaskDetailViewState> = with(actionProcessorHolder) {
  intentsSubject
    .compose<TaskDetailIntent>(intentFilter)
    .map(TaskDetailViewModel.Companion::actionFromIntent)
    .actionProcessor()
    ...
}

or

// processor holder

fun actionProcessor(observable: Observable<TasksAction>) = observable.publish {
    ... 
}

// view model 

fun Observable<TasksAction>.actionProcessor() = actionProcessorHolder.actionProcessor(this)

fun compose(): Observable<TasksViewState> = intentsSubject
  .compose(intentFilter)
  .map(this::actionFromIntent)
  .actionProcessor()
  ...
}

Appears to work the same, but not sure if I'm a fan. Anyway, thanks again!