UseCase<T, Params> class
abstract
The abstract UseCase to be implemented by all usecases.
T
Is the type to be returned by the UseCase to the Presenter
Params
Is the object passed to the usecase containing all the needed parameters
for the UseCase
The UseCase represents a business-level process. It should be written purely
in Dart
and MUST NOT
include any Flutter
code whatsoever. The UseCase
is a part
of the Domain
module of the application in the Clean Architecture
.
Dependencies used by the UseCase must be injected by the Presenter. The UseCase
is essentially an Stream
managing class. When the execute() function is triggered
by the UseCase, an Stream
is built using the buildUseCaseStream()
method, subscribed to
by the Observer passed, and passed any required params
. The StreamSubscription is then added
to a CompositeSubscription
. This is later disposed when dispose()
is called.
When extended, the extending class should override buildUseCaseStream(), where the behavior and functionality
of the UseCase are defined. This method will return the Stream
to be subscribed to, and will fire events to
the Observer
in the Presenter.
Get a list of User
example:
// In this case, no parameters were needed. Hence, void. Otherwise, change to appropriate.
// Typically, a GetUsersUseCaseParams class is defined and wrapped around the parameters
class GetUsersUseCase extends UseCase<List<User>, void> {
final UsersRepository _usersRepository; // some dependency to be injected
// the functionality is hidden behind this
// abstract class defined in the Domain module
// It should be implemented inside the Data or Device
// module and passed polymorphically.
GetUsersUseCase(this._usersRepository);
@override
// Since the parameter type is void, `_` ignores the parameter. Change according to the type
// used in the template.
Future<Stream<GetSponsorsUseCaseResponse>> buildUseCaseStream(_) async {
final StreamController<GetSponsorsUseCaseResponse> controller = StreamController();
try {
// get users
List<User> users = await _usersRepository.getAllUsers();
// Adding it triggers the .onNext() in the `Observer`
// It is usually better to wrap the reponse inside a respose object.
controller.add(users);
logger.finest('GetUsersUseCase successful.');
controller.close();
} catch (e) {
print(e);
logger.severe('GetUsersUseCase unsuccessful.');
// Trigger .onError
controller.addError(e);
}
return Stream(controller.stream);
}
}
The dependencies injected into the UseCase MUST
be in the form of abstract
classes only, in order
to act as interfaces. These abstract
classes are known as Repositories
. The UseCase MUST NOT
accept
anything as a dependency in the form of a class that contains any implemented code according to the Clean Architecture
.
The abstract
repositories are defined in the Domain
module and implemented in either Device
or Data
modules.
They are then injected polymorphically into the UseCase. The repositories should be injected inwards from the
outermost layer View -> Controller -> Presenter -> UseCase
.
For example, the below is a an abstract
repository defined in the Domain
module.
abstract class AuthenticationRepository {
Future<void> register(
{@required String firstName,
@required String lastName,
@required String email,
@required String password});
/// Authenticates a user using his [username] and [password]
Future<void> authenticate(
{@required String email, @required String password});
/// Returns whether the [User] is authenticated.
Future<bool> isAuthenticated();
/// Returns the current authenticated [User].
Future<User> getCurrentUser();
/// Resets the password of a [User]
Future<void> forgotPassword(String email);
/// Logs out the [User]
Future<void> logout();
}
- Implementers
Constructors
- UseCase()
Properties
- hashCode → int
-
The hash code for this object.
no setterinherited
- logger → Logger
-
no setter
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
Methods
-
buildUseCaseStream(
Params? params) → Future< Stream< T?> > -
Builds the
Stream
to be subscribed to.Params
is required by the UseCase to retrieve the appropraite data from the repository -
dispose(
) → void - Disposes (unsubscribes) from the Stream
-
execute(
Observer< T> observer, [Params? params]) → void -
Subscribes to the
Observerable
with the Observer callback functions. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited