1. Appflowy 之 Bloc和freezed,理解Bloc和模式匹配

Talk is cheap, Show me the code

Bloc是什么?

Bloc 全称Business Logic Component, 核心思想是将界面和业务逻辑分离,并通过单项数据流的方式来管理状态。

Flutter 提供了StatelessWidget 处理无状态的UI,StatefulWidget处理有状态的数据,这种分离很好的提供了对不同场景的支持,对于有状态的组件,Flutter开发常见的原生方式是在创建State,将UI剥离出状态,并将状态通过setState()函数重建Widget。本质上就是根据不同的状态生成不同的UI。

如果不做任何分层,仅仅使用Widget,会导致所有的操作,都会在State当中,包括数据的获取,状态的变更,状态依赖的处理。当项目复杂性开始上升,维护项目的成本就会指数级别的增长。

引用一张 Flutter Bloc官网的说明图

1. Appflowy 之 Bloc和freezed,理解Bloc和模式匹配_第1张图片

  • Bloc 是业务逻辑的组件。它负责处理界面和数据之间的交互,执行业务逻辑,并管理状态。
  • Event 是用户界面或其他部分发送给 Bloc 的消息。它可以表示用户的交互、网络请求、定时器触发等事件。
  • State 是表示应用程序状态的对象。Bloc 在执行业务逻辑时,会生成新的状态并将其发送给界面。界面根据接收到的状态来更新自身的呈现。

Bloc模式的优势在于解耦业务逻辑和界面逻辑,使代码更易于测试,维护和扩展。

  • 具体实现概括;在此不深究源代码上的实现,在Android开发技术栈中,RxJava和EventBus都可以类比实现,Bloc基于Stream,on操作很类似于使用RxJava实现EventBus, 原理类似,但管理方向不同,Bloc是一种状态管理范式。

模式匹配是什么?

模式匹配是一种用于检查数据结构的技术手段,比如当我们使用 Switch Case 结构时

void main() {
  String fruit = 'apple';

  switch (fruit) {
    case 'apple':
      print('It\'s an apple!');
      break;
    case 'banana':
      print('It\'s a banana!');
      break;
    default:
      print('Unknown fruit');
  }
}

或者Rust match

fn main() {
    let fruit = "apple";

    match fruit {
        "apple" => println!("It's an apple!"),
        "banana" => println!("It's a banana!"),
        _ => println!("Unknown fruit"),
    }
}

比较的匹配分支必须是不相等的,也就是不能 == 返回True,这种情况下,Enum 和 scale class就比较适合这样的消息定义。

sealed class CounterEvent {}

final class CounterIncrementPressed extends CounterEvent {}

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0) {
    on<CounterIncrementPressed>((event, emit) {
      // handle incoming `CounterIncrementPressed` event
    });
  }
}

使用模式匹配管理状态,有很多优势:

  • 清晰的状态转换
  • 可读性和维护性,代码结构更加扁平。
  • 防止状态遗漏
  • 适应性更强,多状态组合匹配,复杂状态管理更容易

freezed 是什么?

https://github.com/rrousselGit/freezed/blob/master/resources/translations/zh_CN/README.md

简单的说,一个用于数据类 / 联合体 / 模式匹配 / 克隆的代码生成器。

我们可以通过使用Freezed自动生成所需要的数据结构

Dart 3 版本之后,switch支持模式匹配

你可能感兴趣的:(Flutter,flutter)