Skip to content

Commit 40dbb09

Browse files
committed
docs: add BLoC naming conventions
- Added event naming conventions - Added state naming conventions - Updated code examples
1 parent e741ea2 commit 40dbb09

File tree

1 file changed

+88
-5
lines changed

1 file changed

+88
-5
lines changed

memory-bank/systemPatterns.md

Lines changed: 88 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import 'package:my_package/lib/src/widgets/widget_1';
4747
import 'package:my_package/lib/src/widgets/widget_2';
4848
```
4949

50-
Barrel files solve this inefficiency. They export public-facing files, making them available to the rest of the app. It's recommended to create one barrel file per folder, exporting all files required elsewhere. A top-level barrel file should also export the package as a whole.
50+
Barrel files solve this inefficiency. They export public-facing files, making them available to the rest of the app. Create one barrel file per folder, exporting all files required elsewhere. A top-level barrel file should also export the package as a whole.
5151

5252
With barrel files, the feature structure becomes:
5353

@@ -205,6 +205,89 @@ In this example, the API implementation details are now leaked and made known to
205205

206206
BLoC (Business Logic Component) is used to manage the application's state and handle user interactions. Each feature typically has its own BLoC (e.g., `HeadlinesFeedBloc`). BLoCs expose streams of states and receive events as input. The `AppBlocObserver` (not detailed here, but mentioned in the original document) provides centralized logging for BLoC changes and errors.
207207

208+
The following naming conventions are strongly recommended.
209+
210+
### Event Conventions
211+
212+
Events should be named in the **past tense** because events are things that have already occurred from the bloc's perspective.
213+
214+
#### Anatomy
215+
216+
`BlocSubject` + `Noun (optional)` + `Verb (event)`
217+
218+
Initial load events should follow the convention: `BlocSubject` + `Started`
219+
220+
The base event class should be named: `BlocSubject` + `Event`.
221+
222+
#### Examples
223+
224+
**Good**
225+
226+
* `CounterIncremented`
227+
* `HeadlinesFeedLoaded`
228+
* `UserLoginSubmitted`
229+
230+
**Bad**
231+
232+
* `IncrementCounter`
233+
* `LoadHeadlines`
234+
* `SubmitLogin`
235+
236+
### State Conventions
237+
238+
States should be nouns because a state is just a snapshot at a particular point in time. There are two common ways to represent state: using subclasses or using a single class.
239+
240+
#### Anatomy
241+
242+
##### Subclasses
243+
244+
`BlocSubject` + `Verb (action)` + `State`
245+
246+
When representing the state as multiple subclasses `State` should be one of the following:
247+
248+
`Initial` | `Success` | `Failure` | `InProgress`
249+
250+
Initial states should follow the convention: `BlocSubject` + `Initial`.
251+
252+
##### Single Class
253+
254+
`BlocSubject` + `State`
255+
256+
When representing the state as a single base class an enum named `BlocSubject` + `Status` should be used to represent the status of the state:
257+
258+
`initial` | `success` | `failure` | `loading`.
259+
260+
The base state class should always be named: `BlocSubject` + `State`.
261+
262+
#### Examples
263+
264+
**Good**
265+
266+
##### Subclasses
267+
268+
* `CounterInitial`
269+
* `CounterIncrementedSuccess`
270+
* `HeadlinesFeedLoadFailure`
271+
* `UserLoginSuccess`
272+
273+
##### Single Class
274+
275+
* `CounterState` (with `CounterStatus` enum)
276+
* `HeadlinesFeedState` (with `HeadlinesFeedStatus` enum)
277+
* `UserState` (with `UserStatus` enum)
278+
279+
**Bad**
280+
281+
##### Subclasses
282+
* `CounterIncrementing`
283+
* `HeadlinesFeedLoad`
284+
* `LoginUser`
285+
286+
##### Single Class
287+
* `Counter`
288+
* `Headlines`
289+
* `Login`
290+
208291
There are two main approaches to handling states emitted from BLoCs:
209292

210293
1. **Enum for Status within a Single State Class:** Useful for persisting previous data while updating specific fields. Common in scenarios like forms or incremental loading.
@@ -326,7 +409,7 @@ if (email.isValid) {
326409
// ...
327410
}
328411
```
329-
- Consider using dedicated data models instead of record types for complex scenarios or when values are used across multiple files.
412+
- Use dedicated data models instead of record types for complex scenarios or when values are used across multiple files.
330413

331414
## Repository Pattern
332415

@@ -356,7 +439,7 @@ Each feature typically has a "page" widget and a "view" widget. This promotes se
356439
- Gathering dependencies from the context (e.g., using `context.read`).
357440
- Providing these dependencies to the `View` (typically via a `BlocProvider`).
358441

359-
- **View Widget** (e.g., `_HeadlinesFeedView`): A `StatefulWidget` or `StatelessWidget` responsible for:
442+
- **View Widget** (e.g., `_HeadlinesFeedView`): A `StatelessWidget` responsible for:
360443
- Building the UI based on the current state of the BLoC.
361444
- Handling user interactions and dispatching events to the BLoC.
362445
- Receiving dependencies from the `Page`.
@@ -405,7 +488,7 @@ The `View` constructor should be annotated with `@visibleForTesting` to prevent
405488

406489
## Use Standalone Widgets over Helper Methods
407490

408-
When a widget's build method becomes complex, prefer creating new standalone widgets instead of helper methods that return widgets.
491+
When a widget's build method becomes complex, always prefer creating new standalone widgets instead of helper methods that return widgets.
409492

410493
- **Benefits:**
411494
- **Testability:** Each widget can be tested independently.
@@ -484,7 +567,7 @@ Proper error handling is crucial. Follow these practices:
484567

485568
## Testing
486569

487-
- Aim for 100% test coverage.
570+
- Strive for 100% test coverage.
488571
- Organize test files to mirror the project structure (e.g., `test/models/model_a_test.dart` for `lib/models/model_a.dart`).
489572
- Assert test results using `expect` or `verify`.
490573
- Use matchers with expectations (e.g., `expect(value, equals(expectedValue))`).

0 commit comments

Comments
 (0)