You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/why-bloc.md
+61-1Lines changed: 61 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -23,4 +23,64 @@ Bloc was designed with three core values in mind.
23
23
***Powerful**: Help make amazing, complex applications by composing them from smaller components;
24
24
***Testable**: Easily test every aspect of your app so you can iterate with confidence.
25
25
26
-
Overall, Bloc attempts to make state changes predictable by regulating when a state change can occur, and enforcing a single way to change state throughout an app.
26
+
Overall, Bloc attempts to make state changes predictable by regulating when a state change can occur, and enforcing a single way to change state throughout an app.
27
+
28
+
## Bloc vs. ViewModel
29
+
30
+
MVVM has been the default state management pattern on Android for years, thanks to Google's official Lifecycle packages which included lifecycle-aware ViewModel and LiveData components.
31
+
32
+
But Jetpack Compose has no notion of the application lifecycle, which makes one of `androidx.lifecycle.ViewModel`'s main benefits moot.
33
+
34
+
Of course, Compose still has full support for using `androidx.lifecycle` components. But thanks to the fundamentally new architecture of Compose, there's no inherent benefit to using them. This means that you can choose whichever pattern you prefer, or whichever works best for your project and team.
35
+
36
+
Let's consider our Counter example. Here's what it looks like in Bloc:
37
+
38
+
```kotlin
39
+
sealedclassCounterEvent
40
+
41
+
object CounterIncremented: CounterEvent()
42
+
43
+
classCounterBloc: Bloc<CounterEvent, Int>(0) {
44
+
init {
45
+
on<CounterIncremented> {
46
+
emit(state +1)
47
+
}
48
+
}
49
+
}
50
+
```
51
+
52
+
And here's an equivalent ViewModel:
53
+
54
+
```kotlin
55
+
classCounterViewModel: ViewModel() {
56
+
val counter =MutableLiveData<Int>(0)
57
+
58
+
funincrement() {
59
+
counter.postValue(counter.value!!+1)
60
+
}
61
+
}
62
+
```
63
+
64
+
The Bloc has a couple of advantages:
65
+
66
+
* The implementation enforces the use of a single type to represent the state; in this case, and `Int`. This is a great way of making sure you're following the single-responsibility principle of [SOLID](https://en.wikipedia.org/wiki/SOLID) object-oriented programming: the Bloc can only be used to represent one aspect of the application's state. By contrast, the ViewModel is fully open to being bloated with other values, which dilutes its ability to have a single responsibility.
67
+
* The Bloc is easier to instantiate: it doesn't require any special factories as it doesn't depend on anything from the Android framework.
68
+
* The Bloc is also cross-platform; you can use it in any Kotlin code, whereas the ViewModel is Android-only due to its dependency on the Android framework.
69
+
* Unlike ViewModels, which tend to represent all UI elements on a particular screen, Blocs can be totally separated from your UI and instead represent the state of a particular piece of data. It's much easier to use a Bloc across multiple UI elements than it is to share a ViewModel.
70
+
71
+
The ViewModel also has some advantages:
72
+
73
+
* It's much more familiar to a lot of Android developers, which may be an advantage if you're working on a team.
74
+
* It's backwards-compatible with legacy Android UI (Activities and Fragments), making it much easier to use in legacy codebases which are slowly moving towards Compose
75
+
* It's flexible, and allows developers to make their own rules about how they want to implement state management.
76
+
* There is a little less boilerplate
77
+
78
+
Of course, we musn't forget that Cubit is also an option, and provides many of the benefits of Bloc without the associated boilerplate:
79
+
80
+
```kotlin
81
+
classCounterCubit: Cubit<Int>(0) {
82
+
suspendfunincrement = emit(state + 1)
83
+
}
84
+
```
85
+
86
+
For simple states like the Counter, `Cubit` is probably the best of both worlds!
0 commit comments