В моем приложении есть функция, которая имеет некоторую частную информацию о состоянии и некоторую общедоступную информацию.Как я могу избавиться от изменяемой частной переменной состояния?Как получить приватное состояние в цепочку?
Я только недавно узнал о функциональном программировании и хотел преобразовать эту функцию в более fp-подобный подход.
Это мой подход до сих порв качестве простого примера.
sealed class PublicState {
data class Data(val a:Int, val b:Int):PublicState()
object Pending : PublicState()
}
data class PrivateState(val a:Int, val b:Int, val x:Int)
sealed class Action {
data class InputC(val c:Int):Action()
data class InputD(val d:Int):Action()
}
sealed class Update {
data class A(val a:Int):Update()
data class B(val b:Int):Update()
object Working : Update()
}
class Feature {
val actions = PublishSubject.create<Action>()
val state = BehaviorSubject.create<PublicState>()
private var privateState = PrivateState(0,0,1)
init {
val startState = privateState.toPublicState()
actions.flatMap {action ->
when (action) {
is Action.InputC -> handleC(action)
is Action.InputD -> handleD(action)
}
}.scan(startState, ::reduce)
.subscribe(state)
}
fun reduce(previousState:PublicState, update: Update):PublicState {
// can't use previousState because Pending has not all information
// I don't want to add the information to pending because state is undefined while pending
return when (update) {
is Update.A -> privateState.copy(a = update.a).toPublicState()
is Update.B -> privateState.copy(b = update.b).toPublicState()
Update.Working -> PublicState.Pending
}
}
fun doAction(action: Action) {
actions.onNext(action)
}
private fun handleC(action:Action.InputC):Observable<Update> {
return Observable.fromCallable {
// time consuming work which uses x
val result = privateState.x + privateState.a + action.c
Update.A(result) as Update
}.startWith(Update.Working)
}
private fun handleD(action:Action.InputD):Observable<Update> {
return Observable.fromCallable {
// time consuming work which uses x
val result = privateState.x + privateState.b + action.d
Update.B(result) as Update
}.startWith(Update.Working)
}
}
private fun PrivateState.toPublicState(): PublicState {
return PublicState.Data(a, b)
}
На самом деле переменных состояния намного больше, чем a, b и x.Но если я хочу, чтобы они были в цепочке, у меня есть гигантская переменная State, и все это раскрывается.Это легче с изменяемой переменной.Есть ли у вас какие-либо предложения, как решить эту проблему?Я также открыт для других моделей, если вы думаете, что это неправильный подход.Моя цель - сохранить какое-то приватное состояние и выставить только PublicState.