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官网的说明图
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支持模式匹配