Compare commits
6 Commits
b033b97917
...
37d9ab748d
Author | SHA1 | Date | |
---|---|---|---|
![]() |
37d9ab748d | ||
![]() |
3e533a5427 | ||
![]() |
02ea266c43 | ||
![]() |
2467bc306a | ||
![]() |
c2f375de6f | ||
![]() |
18b1daa922 |
@ -31,10 +31,10 @@ The Wyatt Architecture for Flutter.
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Usecase
|
- Usecase
|
||||||
* Repository
|
- Repository
|
||||||
* DataSource
|
- DataSource
|
||||||
* Entity
|
- Entity
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@ -75,16 +75,17 @@ abstract class PhotoRepository extends BaseRepository {
|
|||||||
|
|
||||||
> Here the repository is just a proxy of the data sources with result type (to have beautiful error handling).
|
> Here the repository is just a proxy of the data sources with result type (to have beautiful error handling).
|
||||||
|
|
||||||
And finaly create your different usecases by using `UseCase<Parameters, ReturnType>` :
|
And finaly create your different usecases :
|
||||||
|
|
||||||
|
Several use cases are supported :
|
||||||
|
|
||||||
|
- Classic usecase :
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
class RetrieveAllPhoto extends UseCase<QueryParameters, List<Photo>> {
|
class Test extends AsyncUseCase<QueryParameters, List<Photo>>> {
|
||||||
final PhotoRepository _photoRepository;
|
|
||||||
|
|
||||||
RetrieveAllPhotos(this._photoRepository);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<List<Photo>> call(QueryParameters params) {
|
FuturOrResult<List<Photo>>> call(QueryParameters? params) {
|
||||||
final photos = _photoRepository.getAllPhotos(
|
final photos = _photoRepository.getAllPhotos(
|
||||||
start: params.start,
|
start: params.start,
|
||||||
limit: params.limit,
|
limit: params.limit,
|
||||||
@ -94,6 +95,54 @@ class RetrieveAllPhoto extends UseCase<QueryParameters, List<Photo>> {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can add alternatve scenarios and check pre/post conditions using our extensions :
|
||||||
|
|
||||||
|
```dart
|
||||||
|
class SearchPhotos extends AsyncUseCase<QueryParameters, List<Photo>>> {
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOrResult<List<Photo>>> call(QueryParameters? params) {
|
||||||
|
final photos = _photoRepository.getAllPhotos(
|
||||||
|
start: params.start,
|
||||||
|
limit: params.limit,
|
||||||
|
);
|
||||||
|
return photos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<void> onStart(QueryParameters? params) {
|
||||||
|
if(params.start == null || params.limit == null){
|
||||||
|
throw ClientException('Préconndition non valides');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can implement error scenarios overriding `onError`, or check postconditions by overriding `onComplete` .
|
||||||
|
|
||||||
|
- Stream usecase :
|
||||||
|
|
||||||
|
```dart
|
||||||
|
class SearchPhotos extends StreamUseCase<QueryParameters, List<Photo>>> {
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOrResult<Stream<List<Photo>>>> call(QueryParameters? params) {
|
||||||
|
final photos = _photoRepository.getAllPhotos(
|
||||||
|
start: params.start,
|
||||||
|
limit: params.limit,
|
||||||
|
);
|
||||||
|
return photos;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
On this case, observers allow you to add alternative scénarios when data changed, overriding `onData` or `onDone`.
|
||||||
|
|
||||||
|
Please note that to use handlers, call `execute` methodes instead of `call`.
|
||||||
|
|
||||||
> In fact, here we need a new parameter object, so let's create it:
|
> In fact, here we need a new parameter object, so let's create it:
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
|
@ -35,46 +35,47 @@ class PhotoRepositoryImpl extends PhotoRepository {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<void> addPhotoToFavorites(Photo photo) => Result.tryCatchAsync(
|
FutureOrResult<void> addPhotoToFavorites(Photo photo) => Result.tryCatchAsync(
|
||||||
() => _favoriteLocalDataSource.addPhotoToFavorites(photo),
|
() => _favoriteLocalDataSource.addPhotoToFavorites(photo),
|
||||||
(error) => ClientException('Cannot add photo to favorites.'),
|
(error) => ClientException('Cannot add photo to favorites.'),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<bool> checkIfPhotoIsInFavorites(int id) => Result.tryCatchAsync(
|
FutureOrResult<bool> checkIfPhotoIsInFavorites(int id) =>
|
||||||
|
Result.tryCatchAsync(
|
||||||
() => _favoriteLocalDataSource.checkIfPhotoIsInFavorites(id),
|
() => _favoriteLocalDataSource.checkIfPhotoIsInFavorites(id),
|
||||||
(error) =>
|
(error) =>
|
||||||
ClientException('Cannot check if photo `$id` is in favorites.'),
|
ClientException('Cannot check if photo `$id` is in favorites.'),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<void> deletePhotoFromFavorites(int id) => Result.tryCatchAsync(
|
FutureOrResult<void> deletePhotoFromFavorites(int id) => Result.tryCatchAsync(
|
||||||
() => _favoriteLocalDataSource.deletePhotoFromFavorites(id),
|
() => _favoriteLocalDataSource.deletePhotoFromFavorites(id),
|
||||||
(error) => ClientException('Cannot delete photo `$id` from favorites.'),
|
(error) => ClientException('Cannot delete photo `$id` from favorites.'),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<Album> getAlbum(int id) => Result.tryCatchAsync(
|
FutureOrResult<Album> getAlbum(int id) => Result.tryCatchAsync(
|
||||||
() => _albumRemoteDataSource.getAlbum(id),
|
() => _albumRemoteDataSource.getAlbum(id),
|
||||||
(error) => ServerException('Cannot retrieve album $id.'),
|
(error) => ServerException('Cannot retrieve album $id.'),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<List<Album>> getAllAlbums({int? start, int? limit}) =>
|
FutureOrResult<List<Album>> getAllAlbums({int? start, int? limit}) =>
|
||||||
Result.tryCatchAsync(
|
Result.tryCatchAsync(
|
||||||
() => _albumRemoteDataSource.getAllAlbums(start: start, limit: limit),
|
() => _albumRemoteDataSource.getAllAlbums(start: start, limit: limit),
|
||||||
(error) => ServerException('Cannot retrieve all albums.'),
|
(error) => ServerException('Cannot retrieve all albums.'),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<List<Photo>> getAllPhotos({int? start, int? limit}) async =>
|
FutureOrResult<List<Photo>> getAllPhotos({int? start, int? limit}) async =>
|
||||||
Result.tryCatchAsync(
|
Result.tryCatchAsync(
|
||||||
() => _photoRemoteDataSource.getAllPhotos(start: start, limit: limit),
|
() => _photoRemoteDataSource.getAllPhotos(start: start, limit: limit),
|
||||||
(error) => ServerException('Cannot retrieve all photos.'),
|
(error) => ServerException('Cannot retrieve all photos.'),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<List<Photo>> getAllPhotosFromFavorites() async {
|
FutureOrResult<List<Photo>> getAllPhotosFromFavorites() async {
|
||||||
try {
|
try {
|
||||||
final response = <Photo>[];
|
final response = <Photo>[];
|
||||||
final favorites =
|
final favorites =
|
||||||
@ -95,13 +96,13 @@ class PhotoRepositoryImpl extends PhotoRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<Photo> getPhoto(int id) => Result.tryCatchAsync(
|
FutureOrResult<Photo> getPhoto(int id) => Result.tryCatchAsync(
|
||||||
() => _photoRemoteDataSource.getPhoto(id),
|
() => _photoRemoteDataSource.getPhoto(id),
|
||||||
(error) => ServerException('Cannot retrieve photo $id.'),
|
(error) => ServerException('Cannot retrieve photo $id.'),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<List<Photo>> getPhotosFromAlbum(
|
FutureOrResult<List<Photo>> getPhotosFromAlbum(
|
||||||
int albumId, {
|
int albumId, {
|
||||||
int? start,
|
int? start,
|
||||||
int? limit,
|
int? limit,
|
||||||
|
@ -19,17 +19,17 @@ import 'package:architecture_example/domain/entities/photo.dart';
|
|||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||||
|
|
||||||
abstract class PhotoRepository extends BaseRepository {
|
abstract class PhotoRepository extends BaseRepository {
|
||||||
FutureResult<Album> getAlbum(int id);
|
FutureOrResult<Album> getAlbum(int id);
|
||||||
FutureResult<List<Album>> getAllAlbums({int? start, int? limit});
|
FutureOrResult<List<Album>> getAllAlbums({int? start, int? limit});
|
||||||
FutureResult<Photo> getPhoto(int id);
|
FutureOrResult<Photo> getPhoto(int id);
|
||||||
FutureResult<List<Photo>> getAllPhotos({int? start, int? limit});
|
FutureOrResult<List<Photo>> getAllPhotos({int? start, int? limit});
|
||||||
FutureResult<List<Photo>> getPhotosFromAlbum(
|
FutureOrResult<List<Photo>> getPhotosFromAlbum(
|
||||||
int albumId, {
|
int albumId, {
|
||||||
int? start,
|
int? start,
|
||||||
int? limit,
|
int? limit,
|
||||||
});
|
});
|
||||||
FutureResult<void> addPhotoToFavorites(Photo photo);
|
FutureOrResult<void> addPhotoToFavorites(Photo photo);
|
||||||
FutureResult<void> deletePhotoFromFavorites(int id);
|
FutureOrResult<void> deletePhotoFromFavorites(int id);
|
||||||
FutureResult<List<Photo>> getAllPhotosFromFavorites();
|
FutureOrResult<List<Photo>> getAllPhotosFromFavorites();
|
||||||
FutureResult<bool> checkIfPhotoIsInFavorites(int id);
|
FutureOrResult<bool> checkIfPhotoIsInFavorites(int id);
|
||||||
}
|
}
|
||||||
|
@ -14,18 +14,27 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:architecture_example/domain/entities/photo.dart';
|
import 'package:architecture_example/domain/entities/photo.dart';
|
||||||
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||||
|
|
||||||
class AddPhotoToFavorites extends UseCase<Photo, List<Photo>> {
|
class AddPhotoToFavorites extends AsyncUseCase<Photo, List<Photo>> {
|
||||||
final PhotoRepository _photoRepository;
|
final PhotoRepository _photoRepository;
|
||||||
|
|
||||||
AddPhotoToFavorites(this._photoRepository);
|
AddPhotoToFavorites(this._photoRepository);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<List<Photo>> call(Photo params) async {
|
FutureOrResult<List<Photo>> call(Photo? params) async {
|
||||||
await _photoRepository.addPhotoToFavorites(params);
|
await _photoRepository.addPhotoToFavorites(params!);
|
||||||
return _photoRepository.getAllPhotosFromFavorites();
|
return _photoRepository.getAllPhotosFromFavorites();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<void> onStart(Photo? params) {
|
||||||
|
if (params == null) {
|
||||||
|
throw ClientException('Photo cannot be null');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,15 +14,24 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||||
|
|
||||||
class CheckIfPhotoIsInFavorites extends UseCase<int, bool> {
|
class CheckIfPhotoIsInFavorites extends AsyncUseCase<int, bool> {
|
||||||
final PhotoRepository _photoRepository;
|
final PhotoRepository _photoRepository;
|
||||||
|
|
||||||
CheckIfPhotoIsInFavorites(this._photoRepository);
|
CheckIfPhotoIsInFavorites(this._photoRepository);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<bool> call(int params) async =>
|
FutureOrResult<bool> call(int? params) async =>
|
||||||
_photoRepository.checkIfPhotoIsInFavorites(params);
|
_photoRepository.checkIfPhotoIsInFavorites(params!);
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<void> onStart(int? params) {
|
||||||
|
if (params == null) {
|
||||||
|
throw ClientException('id cannot be null');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,13 +18,13 @@ import 'package:architecture_example/domain/entities/photo.dart';
|
|||||||
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||||
|
|
||||||
class DisplayFavorites extends UseCase<void, List<Photo>> {
|
class DisplayFavorites extends AsyncUseCase<NoParam, List<Photo>> {
|
||||||
final PhotoRepository _photoRepository;
|
final PhotoRepository _photoRepository;
|
||||||
|
|
||||||
DisplayFavorites(this._photoRepository);
|
DisplayFavorites(this._photoRepository);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<List<Photo>> call(void params) {
|
FutureOrResult<List<Photo>> call(void params) {
|
||||||
final photos = _photoRepository.getAllPhotosFromFavorites();
|
final photos = _photoRepository.getAllPhotosFromFavorites();
|
||||||
return photos;
|
return photos;
|
||||||
}
|
}
|
||||||
|
@ -14,18 +14,27 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:architecture_example/domain/entities/photo.dart';
|
import 'package:architecture_example/domain/entities/photo.dart';
|
||||||
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||||
|
|
||||||
class DisplayPhoto extends UseCase<int, Photo> {
|
class DisplayPhoto extends AsyncUseCase<int, Photo> {
|
||||||
final PhotoRepository _photoRepository;
|
final PhotoRepository _photoRepository;
|
||||||
|
|
||||||
DisplayPhoto(this._photoRepository);
|
DisplayPhoto(this._photoRepository);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<Photo> call(int params) {
|
FutureOrResult<Photo> call(int? params) {
|
||||||
final photo = _photoRepository.getPhoto(params);
|
final photo = _photoRepository.getPhoto(params!);
|
||||||
return photo;
|
return photo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<void> onStart(int? params) {
|
||||||
|
if (params == null) {
|
||||||
|
throw ClientException('id cannot be null');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,24 +14,33 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:architecture_example/domain/entities/photo.dart';
|
import 'package:architecture_example/domain/entities/photo.dart';
|
||||||
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
||||||
import 'package:architecture_example/domain/usecases/photos/params/query_parameters.dart';
|
import 'package:architecture_example/domain/usecases/photos/params/query_parameters.dart';
|
||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||||
|
|
||||||
class OpenAlbum extends UseCase<QueryParameters, List<Photo>> {
|
class OpenAlbum extends AsyncUseCase<QueryParameters, List<Photo>> {
|
||||||
final PhotoRepository _photoRepository;
|
final PhotoRepository _photoRepository;
|
||||||
|
|
||||||
OpenAlbum(this._photoRepository);
|
OpenAlbum(this._photoRepository);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<List<Photo>> call(QueryParameters params) {
|
FutureOrResult<List<Photo>> call(QueryParameters? params) {
|
||||||
final photos = _photoRepository.getPhotosFromAlbum(
|
final photos = _photoRepository.getPhotosFromAlbum(
|
||||||
params.albumId,
|
params!.albumId,
|
||||||
start: params.start,
|
start: params.start,
|
||||||
limit: params.limit,
|
limit: params.limit,
|
||||||
);
|
);
|
||||||
|
|
||||||
return photos;
|
return photos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<void> onStart(QueryParameters? params) {
|
||||||
|
if (params == null) {
|
||||||
|
throw ClientException('params cannot be null');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,18 +14,27 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:architecture_example/domain/entities/photo.dart';
|
import 'package:architecture_example/domain/entities/photo.dart';
|
||||||
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||||
|
|
||||||
class RemovePhotoFromFavorites extends UseCase<int, List<Photo>> {
|
class RemovePhotoFromFavorites extends AsyncUseCase<int, List<Photo>> {
|
||||||
final PhotoRepository _photoRepository;
|
final PhotoRepository _photoRepository;
|
||||||
|
|
||||||
RemovePhotoFromFavorites(this._photoRepository);
|
RemovePhotoFromFavorites(this._photoRepository);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<List<Photo>> call(int params) async {
|
FutureOrResult<List<Photo>> call(int? params) async {
|
||||||
await _photoRepository.deletePhotoFromFavorites(params);
|
await _photoRepository.deletePhotoFromFavorites(params!);
|
||||||
return _photoRepository.getAllPhotosFromFavorites();
|
return _photoRepository.getAllPhotosFromFavorites();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<void> onStart(int? params) {
|
||||||
|
if (params == null) {
|
||||||
|
throw ClientException('id cannot be null');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,22 +14,31 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:architecture_example/domain/entities/album.dart';
|
import 'package:architecture_example/domain/entities/album.dart';
|
||||||
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
import 'package:architecture_example/domain/repositories/photo_repository.dart';
|
||||||
import 'package:architecture_example/domain/usecases/photos/params/query_parameters.dart';
|
import 'package:architecture_example/domain/usecases/photos/params/query_parameters.dart';
|
||||||
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||||
|
|
||||||
class RetrieveAllAlbums extends UseCase<QueryParameters, List<Album>> {
|
class RetrieveAllAlbums extends AsyncUseCase<QueryParameters, List<Album>> {
|
||||||
final PhotoRepository _photoRepository;
|
final PhotoRepository _photoRepository;
|
||||||
|
|
||||||
RetrieveAllAlbums(this._photoRepository);
|
RetrieveAllAlbums(this._photoRepository);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureResult<List<Album>> call(QueryParameters params) {
|
FutureOrResult<List<Album>> call(QueryParameters? params) {
|
||||||
final albums = _photoRepository.getAllAlbums(
|
final albums = _photoRepository.getAllAlbums(
|
||||||
start: params.start,
|
start: params!.start,
|
||||||
limit: params.limit,
|
limit: params.limit,
|
||||||
);
|
);
|
||||||
return albums;
|
return albums;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
FutureOr<void> onStart(QueryParameters? params) {
|
||||||
|
if (params == null) {
|
||||||
|
throw ClientException('params cannot be null');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (C) 2022 WYATT GROUP
|
||||||
|
// Please see the AUTHORS file for details.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:wyatt_architecture/wyatt_architecture.dart';
|
||||||
|
|
||||||
|
/// Usecase observers
|
||||||
|
mixin Observer<Parameters, ReturnType> {
|
||||||
|
/// Called before usecase is runned.
|
||||||
|
/// Usefull to check the preconditions
|
||||||
|
FutureOr<void> onStart(Parameters? params) {}
|
||||||
|
|
||||||
|
/// Called when error occures during main scenario
|
||||||
|
/// Usefull to run alternative scenario
|
||||||
|
FutureOr<void> onError(AppException? error) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specific observer for classic usecase
|
||||||
|
mixin AsyncObserver<ReturnType> {
|
||||||
|
FutureOr<void> onComplete(ReturnType? data) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specific observer for stream case usecase
|
||||||
|
mixin StreamObserver<ReturnType> {
|
||||||
|
/// Replaces the data event handler of this subscription.
|
||||||
|
void onDone() {}
|
||||||
|
|
||||||
|
/// Replaces the done event handler of this subscription.
|
||||||
|
void onData(ReturnType? data) {}
|
||||||
|
}
|
@ -14,14 +14,70 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:wyatt_architecture/src/core/exceptions/exceptions.dart';
|
import 'package:wyatt_architecture/src/core/exceptions/exceptions.dart';
|
||||||
|
import 'package:wyatt_architecture/src/domain/usecases/observers.dart';
|
||||||
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
import 'package:wyatt_type_utils/wyatt_type_utils.dart';
|
||||||
|
|
||||||
typedef FutureResult<T> = Future<Result<T, AppException>>;
|
typedef FutureOrResult<T> = FutureOr<Result<T, AppException>>;
|
||||||
typedef StreamResult<T> = Stream<Result<T, AppException>>;
|
typedef StreamResult<T> = Stream<Result<T, AppException>>;
|
||||||
typedef Res<T> = Result<T, AppException>;
|
|
||||||
|
|
||||||
// ignore: one_member_abstracts
|
/// Abstract class of a use case
|
||||||
abstract class UseCase<Parameters, ReturnType> {
|
abstract class BaseUseCase<Parameters, ReturnType> {
|
||||||
FutureResult<ReturnType> call(Parameters params);
|
/// Run use case scenarios
|
||||||
|
ReturnType execute(Parameters parameters);
|
||||||
|
|
||||||
|
/// Private function to implement main scenario
|
||||||
|
/// of your usecase.
|
||||||
|
ReturnType call(Parameters params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Abstract class of a use case that deals specifically
|
||||||
|
/// with the response and its state.
|
||||||
|
abstract class UseCase<Parameters, ReturnType>
|
||||||
|
extends BaseUseCase<Parameters?, FutureOrResult<ReturnType>>
|
||||||
|
with Observer<Parameters, ReturnType> {
|
||||||
|
FutureOr<void> _onSuccess(ReturnType data);
|
||||||
|
|
||||||
|
/// Supports the result of the main scenario and integrates
|
||||||
|
/// some alternative scenarios if necessary.
|
||||||
|
@override
|
||||||
|
FutureOrResult<ReturnType> execute(Parameters? parameters) =>
|
||||||
|
Result.tryCatchAsync(
|
||||||
|
() async {
|
||||||
|
await onStart(parameters);
|
||||||
|
final response = await call(parameters);
|
||||||
|
if (response.isErr) {
|
||||||
|
await onError(response.err);
|
||||||
|
} else if (response.isOk && response.ok != null) {
|
||||||
|
await _onSuccess(response.ok as ReturnType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.ok!;
|
||||||
|
},
|
||||||
|
(error) => ClientException(
|
||||||
|
error.toString(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Abtstract classic usecase.
|
||||||
|
abstract class AsyncUseCase<Parameters, ReturnType>
|
||||||
|
extends UseCase<Parameters?, ReturnType> with AsyncObserver<ReturnType> {
|
||||||
|
@override
|
||||||
|
FutureOr<void> _onSuccess(ReturnType data) => onComplete(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Abstract specific usecase bases on streams
|
||||||
|
abstract class StreamUseCase<Parameters, ReturnType>
|
||||||
|
extends UseCase<Parameters?, Stream<ReturnType>>
|
||||||
|
with StreamObserver<ReturnType> {
|
||||||
|
@override
|
||||||
|
FutureOr<void> _onSuccess(Stream<ReturnType> data) {
|
||||||
|
data.listen(
|
||||||
|
onData,
|
||||||
|
onDone: onDone,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,4 +15,5 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
export 'no_param.dart';
|
export 'no_param.dart';
|
||||||
|
export 'observers.dart';
|
||||||
export 'usecase.dart';
|
export 'usecase.dart';
|
||||||
|
BIN
packages/wyatt_architecture/models/class_model.png
Normal file
BIN
packages/wyatt_architecture/models/class_model.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 117 KiB |
86
packages/wyatt_architecture/models/class_model.puml
Normal file
86
packages/wyatt_architecture/models/class_model.puml
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
@startuml
|
||||||
|
set namespaceSeparator ::
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::core::exceptions::exceptions.dart::AppException" {
|
||||||
|
+String? message
|
||||||
|
+String toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
"dart::core::Exception" <|-- "wyatt_architecture::src::core::exceptions::exceptions.dart::AppException"
|
||||||
|
|
||||||
|
class "wyatt_architecture::src::core::exceptions::exceptions.dart::ClientException" {
|
||||||
|
}
|
||||||
|
|
||||||
|
"wyatt_architecture::src::core::exceptions::exceptions.dart::AppException" <|-- "wyatt_architecture::src::core::exceptions::exceptions.dart::ClientException"
|
||||||
|
class "wyatt_architecture::src::core::exceptions::exceptions.dart::ServerException" {
|
||||||
|
}
|
||||||
|
|
||||||
|
"wyatt_architecture::src::core::exceptions::exceptions.dart::AppException" <|-- "wyatt_architecture::src::core::exceptions::exceptions.dart::ServerException"
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::repositories::base_repository.dart::BaseRepository" {
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::data_sources::local::base_local_data_source.dart::BaseLocalDataSource" {
|
||||||
|
}
|
||||||
|
|
||||||
|
"wyatt_architecture::src::domain::data_sources::base_data_source.dart::BaseDataSource" <|-- "wyatt_architecture::src::domain::data_sources::local::base_local_data_source.dart::BaseLocalDataSource"
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::data_sources::base_data_source.dart::BaseDataSource" {
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::data_sources::remote::base_remote_data_source.dart::BaseRemoteDataSource" {
|
||||||
|
}
|
||||||
|
|
||||||
|
"wyatt_architecture::src::domain::data_sources::base_data_source.dart::BaseDataSource" <|-- "wyatt_architecture::src::domain::data_sources::remote::base_remote_data_source.dart::BaseRemoteDataSource"
|
||||||
|
|
||||||
|
class "wyatt_architecture::src::domain::usecases::no_param.dart::NoParam" {
|
||||||
|
}
|
||||||
|
|
||||||
|
"wyatt_architecture::src::domain::entities::entity.dart::Entity" <|-- "wyatt_architecture::src::domain::usecases::no_param.dart::NoParam"
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::usecases::observers.dart::Observer" {
|
||||||
|
+FutureOr<void> onStart()
|
||||||
|
+FutureOr<void> onError()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::usecases::observers.dart::AsyncObserver" {
|
||||||
|
+FutureOr<void> onComplete()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::usecases::observers.dart::StreamObserver" {
|
||||||
|
+void onDone()
|
||||||
|
+void onData()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::usecases::usecase.dart::BaseUseCase" {
|
||||||
|
+ReturnType execute()
|
||||||
|
+ReturnType call()
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::usecases::usecase.dart::UseCase" {
|
||||||
|
-FutureOr<void> _onSuccess()
|
||||||
|
+FutureOr<Result<ReturnType, AppException>> execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
"wyatt_architecture::src::domain::usecases::usecase.dart::BaseUseCase" <|-- "wyatt_architecture::src::domain::usecases::usecase.dart::UseCase"
|
||||||
|
"wyatt_architecture::src::domain::usecases::observers.dart::Observer" <|-- "wyatt_architecture::src::domain::usecases::usecase.dart::UseCase"
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::usecases::usecase.dart::AsyncUseCase" {
|
||||||
|
-FutureOr<void> _onSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
"wyatt_architecture::src::domain::usecases::usecase.dart::UseCase" <|-- "wyatt_architecture::src::domain::usecases::usecase.dart::AsyncUseCase"
|
||||||
|
"wyatt_architecture::src::domain::usecases::observers.dart::AsyncObserver" <|-- "wyatt_architecture::src::domain::usecases::usecase.dart::AsyncUseCase"
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::usecases::usecase.dart::StreamUseCase" {
|
||||||
|
-FutureOr<void> _onSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
"wyatt_architecture::src::domain::usecases::usecase.dart::UseCase" <|-- "wyatt_architecture::src::domain::usecases::usecase.dart::StreamUseCase"
|
||||||
|
"wyatt_architecture::src::domain::usecases::observers.dart::StreamObserver" <|-- "wyatt_architecture::src::domain::usecases::usecase.dart::StreamUseCase"
|
||||||
|
|
||||||
|
abstract class "wyatt_architecture::src::domain::entities::entity.dart::Entity" {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@enduml
|
Loading…
x
Reference in New Issue
Block a user