基于Resocoder的Clean Architecture:UI如何感知外部数据源变更?
关于Resocoder Clean Architecture中UI接收外部数据源变更的实现方案
Resocoder的这套Flutter Clean Architecture变体完全支持UI接收外部数据源(比如API主动推送)的变更通知,核心是利用Dart的Stream(或RxDart的响应式工具)在各层间传递数据流,同时不破坏分层依赖规则。具体实现路径如下:
1. 数据层监听外部变更
在数据层的Remote Data Source中,直接对接外部数据源的推送机制:
- 如果是WebSocket、Firebase实时数据库这类主动推送的服务,在这里建立长连接并监听数据变更事件;
- 如果是需要轮询的REST API,也可以在这里通过
Stream.periodic实现定时拉取。 - 当收到新数据后,将其解析为Domain层定义的
Entity,通过Stream输出。
示例伪代码:
class UserRemoteDataSource { Stream<User> listenToUserUpdates() { // 模拟WebSocket监听用户数据变更 return WebSocketChannel.connect(Uri.parse('wss://api.example.com/user')) .stream .map((event) => User.fromJson(jsonDecode(event))); } }
2. Repository层暴露标准化数据流
Repository作为数据层和Domain层的中间层,将数据源的Stream封装后,按照Domain层定义的抽象接口暴露给上层:
abstract class UserRepository { Stream<User> getUserUpdates(); } class UserRepositoryImpl implements UserRepository { final UserRemoteDataSource remoteDataSource; UserRepositoryImpl(this.remoteDataSource); @override Stream<User> getUserUpdates() { return remoteDataSource.listenToUserUpdates(); } }
3. Presentation层订阅并转换状态
在ViewModel/Cubit(Presentation层)中,订阅Repository的Stream,当收到新数据时,转换为对应的UI状态并emit:
class UserCubit extends Cubit<UserState> { final UserRepository userRepository; StreamSubscription? _subscription; UserCubit(this.userRepository) : super(UserInitial()) { _listenToUserUpdates(); } void _listenToUserUpdates() { _subscription = userRepository.getUserUpdates().listen((user) { emit(UserLoaded(user)); }); } @override Future<void> close() { _subscription?.cancel(); return super.close(); } } abstract class UserState {} class UserInitial extends UserState {} class UserLoaded extends UserState { final User user; UserLoaded(this.user); }
4. UI层监听状态自动刷新
UI组件通过BlocBuilder(或StreamBuilder)监听Presentation层的状态变化,当状态更新时自动重建UI:
BlocBuilder<UserCubit, UserState>( builder: (context, state) { if (state is UserLoaded) { return Text('当前用户:${state.user.name}'); } else { return const CircularProgressIndicator(); } }, )
补充说明
如果是普通REST API的被动场景(比如需要主动拉取同步数据),可以在Presentation层定时调用Use Case获取最新数据,同样通过状态更新触发UI刷新,本质逻辑和主动推送一致。
这套实现完全符合Clean Architecture的依赖规则:外层(UI、Presentation)依赖内层(Domain、Data)的抽象,数据流从最外层的数据源逐步向上传递到UI,没有打破分层边界。
内容的提问来源于stack exchange,提问作者John Andersen
相关产品推荐
相关产品推荐

