Helpers de dominio
JIntent aporta helpers de casos de uso, Either y mappers. Los repositorios, la
persistencia, la red y el caché son responsabilidad de la aplicación que consume
la librería. La organización en capas del ejemplo del contador
(DTO,
mapper,
repositorio,
casos de uso) es opcional. Mantén los
tipos específicos del almacenamiento fuera del estado de la UI y convierte los
fallos esperados en el límite de la operación.
Either es sellado (sealed), por lo que un switch sobre él se comprueba por
exhaustividad:
final text = switch (result) { Left(:final value) => 'Failed: $value', Right(:final value) => 'Got $value',};Left y Right se comparan por valor y por tipo exacto en tiempo de ejecución
(incluidos los argumentos de tipo), de modo que la igualdad es simétrica.
Validación
Sección titulada «Validación»JUseCase<INPUT, OUTPUT> y JSyncUseCase<INPUT, OUTPUT> aceptan validadores
mediante addValidator. Cada UseCaseInputValidator<I> devuelve
Either<Exception, I>.
class PositiveCounter extends JSyncUseCase<int, int> { PositiveCounter() { addValidator((value) => value < 0 ? Left(Exception('Counter must be non-negative')) : Right(value)); }
@override Either<Exception, int> run(int input) => Right(input);}
final result = PositiveCounter().call(3);Llama al caso de uso mediante call (o con la sintaxis de llamada a función) para
ejecutar la validación. Llamar a run directamente omite los validadores. Los
validadores se ejecutan de forma síncrona en orden de registro y se detienen en el
primer Left. Los valores de los validadores exitosos no se pasan a los
siguientes ni a run: todos reciben la entrada original. Las excepciones lanzadas
no se convierten en Left. Los validadores son precondiciones de la operación, no
un sustituto de la autorización en el servidor.
JUseCaseVoid expone solo run; no tiene una cadena de validadores incorporada.
JValidationUtils (de package:jintent/utils.dart) ofrece valores
predeterminados de análisis y comprobaciones de rango, no un framework general de
validación. Consulta los
validadores del
ejemplo y sus pruebas.
Mappers
Sección titulada «Mappers»JMapper<INPUT, OUTPUT> implementa IMapper mediante una única sobrescritura de
map:
class CountLabelMapper extends JMapper<int, String> { @override String map(int value) => 'Count: $value';}
final mapper = CountLabelMapper();final label = mapper.transform(2);final labels = mapper.transformList([1, 2]);final sameLabels = [1, 2].mapWith(mapper);transformconvierte una entrada;transformListdevuelve una lista de salida nueva.transformDynamicaceptaINPUToList<INPUT>y lanzaArgumentErrorpara otros tipos. Prefiere los métodos tipados cuando sea posible.IBiMapper<A, B>defineto(A)yfrom(B)para un mapeo explícito en ambos sentidos. Implementa y prueba ambas direcciones; la invertibilidad no se impone.
Consulta el mapper del contador y sus pruebas.