具有多个流的 Flutter Bloc?

tur*_*eep 5 dart flutter bloc

我最近听说并阅读了很多有关 BLoC 架构的内容,它很有意义,并且与我以前使用过的程序结构相似。

然而,我发现不清楚的一件事是 BLoC 应该实例化并提供可用的流。

让我们考虑应用程序用户有两个按钮,按下这两个按钮将创建两个不同的对象,需要通过BLoC 中的不同方法来处理。我不确定这是否需要创建两个StreamController对象并公开两个接收器,或者它们是否应该共享一个公共对象StreamController,并且使用运行时类型检查来区分操作。

这两种方法如下:第一种方法在 BLoC 中创建两个流控制器:

  final _actionOneController = StreamController<ActionOne>();
  StreamSink<ActionOne> get actionOne => _actionOneController.sink;

  final _actionTwoController = StreamController<ActionTwo>();
  StreamSink<ActionTwo> get actionTwo => _actionTwoController.sink;
Run Code Online (Sandbox Code Playgroud)

通过将两个事件添加到不同的接收器来创建它们:

 Button(child: Text("Action One"), onPressed: () => bloc.actionOne.add(ActionOne(data, data1, data3)),
 Button(child: Text("Action Two"), onPressed: () => bloc.actionTwo.add(ActionTwo(someOtherData)),
Run Code Online (Sandbox Code Playgroud)

并通过分别监听两个流来处理它们。

第二种方法暴露了一个StreamSink

  final _actionController = StreamController<Action>();
  StreamSink<Action> get action => _actionController.sink;
Run Code Online (Sandbox Code Playgroud)

通过将两个事件添加到公共接收器来创建它们:

 Button(child: Text("Action One"), onPressed: () => bloc.action.add(ActionOne(data, data1, data3)),
 Button(child: Text("Action Two"), onPressed: () => bloc.action.add(ActionTwo(someOtherData)),
Run Code Online (Sandbox Code Playgroud)

然后使用检查对象运行时类型的方法来区分 BLoC 中的操作Action

void _actionListener(Action action){
  if(action is ActionOne)
    actionOneHandler(action);
  if(action is ActionTwo)
    actionTwoHandler(action);
}
Run Code Online (Sandbox Code Playgroud)

我想强调的是,这两个操作创建了没有公共字段的不同对象,即它们不共享共同继承的祖先类。

小智 5

顾名思义,BLoC 背后的核心思想是将 UI 和业务规则之间的职责分开,因此取决于您想要如何构建和组织该逻辑。也许如果您为一个简单的屏幕实现一个块,那么您会擅长使用一个流,但是随着您的应用程序变得复杂,您可能需要使用与单个对象相关的逻辑将这些块分解为小块,然后组合它适用于每个屏幕。

要回答这个问题,事实是这取决于具体情况,但是当您强调这两个操作处理不同的对象时,我们建议您在不同的流中处理它,以便很好地分离职责。将来,如果您需要重构和维护代码,会更容易,因为您已经将所有逻辑完全分离了。

这样做的另一个重要优点是,您可以拥有强类型流,并具有所带来的所有好处,在第二种情况下,操作必须位于同一层次结构中才能添加到同一接收器。

希望能帮助到你!