基于Clean Architecture,如何将登录Bloc数据传递至OTP验证Bloc?
基于Clean Architecture实现Verification Bloc获取登录成功数据的方案
在Clean Architecture架构下,核心原则是依赖倒置(内层不依赖外层,外层依赖内层抽象)和职责分离,不能直接让Verification Bloc依赖Login Bloc,需通过内层的实体、用例或抽象仓库传递数据,以下是几种合规的实现方式:
方案1:通过实体/值对象直接传递(适合简单场景)
- 定义域层核心实体:在域层创建
AuthCredentials实体,封装登录成功后的关键数据(如userId、tempAuthToken、otpExpiry等),该实体不依赖任何外层,是架构的核心组件。 - Login Bloc输出成功状态:登录用例执行完成后,Login Bloc发出包含
AuthCredentials的成功状态(例如LoginSuccess(credentials: authCredentials))。 - UI层导航时传递实体:UI监听Login Bloc的成功状态,导航到Verification页面时,将
AuthCredentials作为导航参数传入。 - Verification Bloc初始化接收参数:Verification Bloc的构造函数直接接收
AuthCredentials,后续发起OTP验证请求时直接使用该实体的数据。
该方式完全符合Clean Architecture规则:实体属于最内层域层,表现层(Bloc、UI)依赖域层实体,依赖方向正确。class VerificationBloc extends Bloc<VerificationEvent, VerificationState> { final AuthCredentials credentials; final VerifyOtpUseCase verifyOtpUseCase; VerificationBloc({required this.credentials, required this.verifyOtpUseCase}) : super(VerificationInitial()) { on<SendOtpEvent>((event, emit) async { await verifyOtpUseCase.execute(VerifyOtpParams( token: credentials.tempAuthToken, userId: credentials.userId, )); }); } }
方案2:通过域层用例传递数据(适合复杂业务场景)
- 定义OTP验证用例:在域层创建
StartOtpVerificationUseCase,输入参数为AuthCredentials,用例内部封装OTP请求的业务逻辑(如调用仓库发起验证、处理过期逻辑等)。 - Login Bloc持久化临时凭证:登录成功后,Login Bloc调用域层抽象仓库的
saveTempCredentials(credentials)方法,将临时凭证持久化(数据层实现仓库时处理具体存储逻辑)。 - Verification Bloc调用用例获取数据:Verification Bloc初始化时,调用
GetTempCredentialsUseCase获取保存的AuthCredentials,或在触发OTP事件时将参数传入用例。
该方式将业务逻辑封装在域层用例中,Bloc仅负责触发用例和管理状态,符合职责分离原则,同时遵循依赖倒置(Bloc依赖域层用例抽象)。class StartOtpVerificationUseCase { final AuthRepository authRepository; StartOtpVerificationUseCase(this.authRepository); Future<Either<Failure, OtpResponse>> execute(AuthCredentials credentials) async { return await authRepository.requestOtp(credentials); } }
方案3:通过域层抽象仓库共享会话数据(适合多页面共享登录状态场景)
- 定义域层仓库抽象:在域层创建
AuthRepository抽象,包含saveSession(AuthSession session)和getCurrentSession()方法,AuthSession为域层实体,包含登录后的所有会话数据。 - Login Bloc持久化会话:登录成功后,Login Bloc调用
authRepository.saveSession(AuthSession.fromCredentials(credentials)),将会话数据保存到本地或内存。 - Verification Bloc获取会话数据:Verification Bloc初始化时,调用
authRepository.getCurrentSession()获取会话数据,用于发起OTP验证请求。
该方式通过域层抽象仓库实现数据共享,避免Bloc间直接耦合,同时符合依赖倒置原则(Bloc依赖域层仓库抽象,数据层实现具体逻辑)。class VerificationBloc extends Bloc<VerificationEvent, VerificationState> { final AuthRepository authRepository; final VerifyOtpUseCase verifyOtpUseCase; AuthSession? _currentSession; VerificationBloc({required this.authRepository, required this.verifyOtpUseCase}) : super(VerificationInitial()) { on<LoadSessionEvent>((event, emit) async { final sessionEither = await authRepository.getCurrentSession(); sessionEither.fold( (failure) => emit(VerificationError(failure.message)), (session) { _currentSession = session; emit(VerificationReady(session.userId)); }, ); }); } }
内容的提问来源于stack exchange,提问作者Jsoon
相关产品推荐
相关产品推荐

