具有多个流的 Flutter Bloc?

Flutter Bloc with Multiple Streams?

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

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

让我们假设应用程序用户有两个按钮,按下时将创建两个 distinct 对象,需要由distinct BLoC 中的方法。我不确定这是否需要创建两个 StreamController 对象并公开两个接收器,或者它们是否应该共享一个公共 StreamController 并且这些操作在使用运行时类型检查时有所区别。

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

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

  final _actionTwoController = StreamController<ActionTwo>();
  StreamSink<ActionTwo> get actionTwo => _actionTwoController.sink;

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

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

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

第二种方法公开了一个 StreamSink:

  final _actionController = StreamController<Action>();
  StreamSink<Action> get action => _actionController.sink;

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

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

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

void _actionListener(Action action){
  if(action is ActionOne)
    actionOneHandler(action);
  if(action is ActionTwo)
    actionTwoHandler(action);
}

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

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

要回答这个问题,真实情况视情况而定,但正如您强调这两个操作处理不同的对象一样,建议您在不同的流中处理它以实现良好的职责分离。以后如果你需要重构和维护代码会更容易,因为你已经把所有的逻辑完全分离了。

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

希望对您有所帮助!