← → or space · progress saves for Continue on the roadmap
Goal
Take one working project (Todo file store, expense ledger, or a small CLI) and split lib/ by concern.
Step 1 - Inventory
- List types: plain data vs IO vs orchestration vs string/date helpers.
- Note which files import
dart:ioorhttp(repository side) vs onlydart:core(models, many utils).
Step 2 - Target layout
lib/
main.dart
models/
todo.dart
user.dart
repositories/
todo_file_repository.dart
services/
todo_service.dart
utils/
json_helpers.dart- Names match your domain; extra folders (
cli/,config/) are fine if they clarify.
Step 3 - Move rules
- Models: classes that mostly hold data and
toJson/fromJson; noFileor sockets. - Repositories:
read/writeboundaries; return models or failures, not rawStringeverywhere if you can avoid it. - Services: methods like
addTodo,completeTodo,loadAllthat call repositories and enforce rules. - Utils: pure helpers used in two or more places; otherwise keep next to the single caller.
Step 4 - Fix imports
- Run
dart analyzeafter each batch of moves. - Use
package:your_package/...imports insidelib/for clarity in multi-file packages.
Step 5 - Verify
dart runor tests still pass.dart format .once at the end.
Practice tasks
- Add a fake
TodoRepositoryin-memory next to the file implementation; inject one or the other frommain. - Move JSON decode error handling into
utils/or keep it on the repository—pick one and write one sentence why. - Add
README.mdsection “Structure” with the folder list (only if your repo already uses a root README).