BLOC重构Counter实现(BLOC逻辑处理工程简化)
说明: 本部分完成部分在分支: https://github.com/dragonetail/flutterpoc/tree/2-counter_refactor_simplication
目标: 根据Flutter缺省计数器例子,遵循Bloc的理念实现增减计数器的逻辑和视图分离,在第一步的基础上,抽取BaseBloc实现,简化Bloc的处理逻辑和工程化。
在的counter_bloc.dart基础上,抽取BaseBloc、BaseEvent、BaseState三个抽象基类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
abstract class BaseBloc<Event extends BaseEvent, State extends BaseState>
extends Bloc<Event, State> {
//Event到State映射函数表
Map<Type, Function(Event)> get mapper;
Stream<State> mapEventToState(
Event event,
) async* {
if (mapper == null) {
return;
}
Type type = event.runtimeType;
var function = mapper[type];
if (function == null) {
return;
}
yield* function(event);
}
}
abstract class BaseEvent extends Equatable {
BaseEvent([List props = const []]) : super(props);
}
abstract class BaseState extends Equatable {
BaseState([List props = const []]) : super(props);
}对mapEventToState进行了默认实现,根据
Map<Type, Function(Event)> get mapper
定义的【Event到State映射函数表】进行业务逻辑函数的dispatch操作,简化业务逻辑的if级联判断。再看看counter_bloc.dart的实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43import 'dart:async';
import '../blocs.dart';
class CounterBloc extends BaseBloc<CounterEvent, CounterState> {
CounterState get initialState => CountingState(0);
Map<Type, Function(CounterEvent)> get mapper => {
IncrementEvent: _mapIncrementEventToState,
DecrementEvent: _mapDecrementEventToState,
};
Stream<CounterState> _mapIncrementEventToState(CounterEvent event) async* {
yield CountingState((currentState as CountingState).counter + 1);
}
Stream<CounterState> _mapDecrementEventToState(CounterEvent event) async* {
yield CountingState((currentState as CountingState).counter - 1);
}
}
//Event定义
abstract class CounterEvent extends BaseEvent{
CounterEvent([List props = const []]) : super(props);
}
class IncrementEvent extends CounterEvent{}
class DecrementEvent extends CounterEvent{}
//State定义
abstract class CounterState extends BaseState{
CounterState([List props = const []]) : super(props);
}
class CountingState extends CounterState {
final int counter;
CountingState(this.counter) : super([counter]);
String toString() {
return 'CountingState { counter: $counter }';
}
}通过重载
Map<Type, Function(CounterEvent)> get mapper => {
定义了两个Event类到对应处理方法的映射表。统一映射方法的处理,接受
CounterEvent event
,返回Stream<CounterState>
。同时简化Event和State的定义,整个所有Bloc相关的内容都放到一个文件中,减少文件拆分,简化工程化开发的复杂度。
【研讨】在这个抽取过程中,通过BaseEvent、BaseState的抽取,技术上应该不需要CounterEvent、CounterState进行过渡,直接在映射方法的参数和返回值上使用BaseEvent、BaseState,是不是会更好?
- 结论: 整体上,这样基本对于业务逻辑拆分隔离来说,复杂度已经降低到类似Spring框架的水平附近了。