osam 5.1.5 osam: ^5.1.5 copied to clipboard
State management library inspired SOLID prenciples.
OSAM #
Osam - it is complex solution for fast and quality mobile developing.
First we will talk about is State aka BaseState<T>
object.
The data structure which representing current data in runtime can be called as State.
Example:
class AppState extends BaseState<AppState> {
final counter = Counter();
@override
List<Object> get props => [counter];
}
class Counter extends BaseState<Counter> {
var value = 0;
StateStream<int> get valueStream => propertyStream((state) => state.value);
@override
List<Object> get props => [value];
}
This code means that we have a something like tree of data for our app.
Recommendation: Create a one AppState in main function instead of a lot of states.
The state and it's property are listenable. You can get it by calling 'propertyStream'. It returns StateStream - Bundle with value and it's stream.
Second we talk about is Store.
The purpose of Store is provide 'UseCases'. UseCase could be everything, but I recommend to follow several rules:
- UseCase have access to AppState or sub states by passing it in to constructor.
- State or states in UseCase must be lib private (underscored "_item = 1").
- UseCase should implement interfaces to provide business models or properties of it.
- Only UseCase can change States by calling update method.
- All repositories you need must be provided via constructor in to UseCase.
- UseCase should depends of interfaces not implementations of repositories
abstract class ICounter{
Future<int> increment(int value);
}
class CounterUseCase {
final ICounter _counterRepo;
final AppState _appState;
CounterUseCase(this._counterRepo, this._appState);
Future<void> increment() async {
final lastValue = _appState.counter.value;
final newValue = await _counterRepo.increment(lastValue);
_appState.counter.update((state) => state..value = newValue);
}
StateStream<int> get valueStream => _appState.counter.valueStream;
}
// example