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

Refactor FeatureFactory public API using Params. #398

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- **Breaking**: Removed `FlowFactory` and `Flow`
- **Breaking**: Replace `FragmentStoreBuilder` with `FeaturesBuilder`
- **Breaking**: Rename `FragmentFlowStore` to `FragmentStore`, `FragmentState` to `FragmentOutput`, `FragmentFlowState` to `FragmentState`
- **Breaking**: Making `FeatureFactory` into an abstract class and modifying the `initialize` API to use `Params` wrapper type

## [0.7.1] - June 28, 2022
- **Breaking**: Rename `FragmentBindingBuilder` to `FragmentStoreBuilder`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import io.reactivex.rxjava3.core.Observable
class TestFeatureFactory<Key : FragmentKey>(
private val render: (FragmentKey, Any) -> Unit = { _, _ -> },
private val state: (Key) -> Observable<Any>,

) : FeatureFactory<Unit, Key> {
override fun initialize(dependencies: Unit, key: Key): Feature {
) : FeatureFactory<Unit, Key>() {
override fun Params.initialize(): Feature {
return Feature(
state = state(key),
viewFactory = TestViewFactory { _, value ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,22 @@ package com.instacart.formula.android
* @param Key a type of fragment key that is used to identify this feature.
*
*/
interface FeatureFactory<in Dependencies, in Key : FragmentKey> {
abstract class FeatureFactory<in Dependencies, in Key : FragmentKey> {

inner class Params(
val dependencies: @UnsafeVariance Dependencies,
val key: @UnsafeVariance Key,
)

/**
* Initializes the [Feature] using [Params] provided.
*/
abstract fun Params.initialize(): Feature

/**
* Initializes state observable and a view factory for a specific [key].
*/
fun initialize(dependencies: Dependencies, key: Key): Feature
fun initialize(dependencies: Dependencies, key: Key): Feature {
return Params(dependencies, key).initialize()
}
Comment on lines -43 to +55
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this become private in a follow up?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably not, this function provides a better API to initialize the Feature. It's a final function that delegates to a better internal API for implementation.

  • for implentee use Params.initialize
  • for the consumer use initialize(dependencies, key, other params)

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import com.instacart.formula.android.FragmentKey
internal class MappedFeatureFactory<Component, Dependencies, Key : FragmentKey>(
private val delegate: FeatureFactory<Dependencies, Key>,
private val toDependencies: (Component) -> Dependencies,
) : FeatureFactory<Component, Key> {
override fun initialize(dependencies: Component, key: Key): Feature {
) : FeatureFactory<Component, Key>() {
override fun Params.initialize(): Feature {
return delegate.initialize(
dependencies = toDependencies(dependencies),
key = key,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ class FragmentStoreTest {
}

@Test fun `bind feature factory with to dependencies defined`() {
val myFeatureFactory = object : FeatureFactory<String, MainKey> {
override fun initialize(dependencies: String, key: MainKey): Feature {
val myFeatureFactory = object : FeatureFactory<String, MainKey>() {
override fun Params.initialize(): Feature {
return TestUtils.feature(
stateValue = dependencies
)
Expand Down Expand Up @@ -182,8 +182,8 @@ class FragmentStoreTest {
@Test fun `store returns failure event when feature factory initialization throws an error`() {
val expectedError = RuntimeException("something happened")
val store = FragmentStore.init(FakeComponent()) {
val featureFactory = object : FeatureFactory<FakeComponent, MainKey> {
override fun initialize(dependencies: FakeComponent, key: MainKey): Feature {
val featureFactory = object : FeatureFactory<FakeComponent, MainKey>() {
override fun Params.initialize(): Feature {
throw expectedError
}
}
Expand All @@ -209,8 +209,8 @@ class FragmentStoreTest {
val stateSubject = PublishSubject.create<Any>()

val store = FragmentStore.init {
val featureFactory = object : FeatureFactory<Any, MainKey> {
override fun initialize(dependencies: Any, key: MainKey): Feature {
val featureFactory = object : FeatureFactory<Any, MainKey>() {
override fun Params.initialize(): Feature {
return Feature(
state = stateSubject,
viewFactory = TestViewFactory(),
Expand Down Expand Up @@ -248,8 +248,8 @@ class FragmentStoreTest {
val stateSubject = PublishSubject.create<Any>()

val store = FragmentStore.init {
val featureFactory = object : FeatureFactory<Any, MainKey> {
override fun initialize(dependencies: Any, key: MainKey): Feature {
val featureFactory = object : FeatureFactory<Any, MainKey>() {
override fun Params.initialize(): Feature {
return Feature(
state = stateSubject,
viewFactory = TestViewFactory(),
Expand Down Expand Up @@ -293,8 +293,8 @@ class FragmentStoreTest {

@Test fun `fragment store visible output`() {
val store = FragmentStore.init {
val featureFactory = object : FeatureFactory<Any, MainKey> {
override fun initialize(dependencies: Any, key: MainKey): Feature {
val featureFactory = object : FeatureFactory<Any, MainKey>() {
override fun Params.initialize(): Feature {
return Feature(
state = Observable.just("value"),
viewFactory = TestViewFactory(),
Expand Down Expand Up @@ -360,8 +360,8 @@ class FragmentStoreTest {
private fun FragmentKey.asAddedEvent() = FragmentLifecycleEvent.Added(FragmentId("", this))
private fun FragmentKey.asRemovedEvent() = FragmentLifecycleEvent.Removed(FragmentId("", this))

class TestFeatureFactory<FragmentKeyT : FragmentKey>: FeatureFactory<FakeComponent, FragmentKeyT> {
override fun initialize(dependencies: FakeComponent, key: FragmentKeyT): Feature {
class TestFeatureFactory<FragmentKeyT : FragmentKey>: FeatureFactory<FakeComponent, FragmentKeyT>() {
override fun Params.initialize(): Feature {
return Feature(
state = dependencies.state(key),
viewFactory = TestViewFactory()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import com.instacart.formula.android.compose.ComposeViewFactory
import com.instacart.formula.invoke
import com.instacart.formula.rxjava3.toObservable

class StopwatchFeatureFactory : FeatureFactory<Any, StopwatchKey> {
override fun initialize(dependencies: Any, key: StopwatchKey): Feature {
class StopwatchFeatureFactory : FeatureFactory<Any, StopwatchKey>() {
override fun Params.initialize(): Feature {
return Feature(
state = StopwatchFormula().toObservable(),
viewFactory = StopwatchViewFactory()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ import com.instacart.formula.android.LayoutViewFactory
import com.instacart.formula.android.ViewInstance
import com.instacart.formula.rxjava3.toObservable

class TaskListFeatureFactory : FeatureFactory<TaskListFeatureFactory.Dependencies, TaskListKey> {
class TaskListFeatureFactory : FeatureFactory<TaskListFeatureFactory.Dependencies, TaskListKey>() {
interface Dependencies {
fun taskRepo(): TaskRepo
fun taskListInput(): TaskListFormula.Input
}

override fun initialize(dependencies: Dependencies, key: TaskListKey): Feature {
override fun Params.initialize(): Feature {
// Note: we could create our own internal dagger component here using the dependencies.
val formula = TaskListFormula(dependencies.taskRepo())
return Feature(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import io.reactivex.rxjava3.core.Observable

class NoOpFeatureFactory<FragmentKeyT : FragmentKey>(
private val viewFactory: ViewFactory<FragmentKeyT> = TestViewFactory(),
) : FeatureFactory<Unit, FragmentKeyT> {
override fun initialize(dependencies: Unit, key: FragmentKeyT): Feature {
) : FeatureFactory<Unit, FragmentKeyT>() {
override fun Params.initialize(): Feature {
return Feature(
state = Observable.empty(),
viewFactory = viewFactory,
Expand Down
Loading